Sola dört adım: engerek. Sağa dört adım: bir uçurum. Ölme!


28

Giriş

Bir an için engereklerin ve uçurumun üç yerine sadece iki adım uzakta olduklarını varsayalım .

            o
           ---
Hsss!       |
 ';;' ___  /_\  ___  _
                      |

Maalesef, sadist bir işkencecinin esiri sizsiniz. Sen gerekir her fırsatta sola veya sağa doğru bir adım atmak. Yapmazsan, seni anında vururlar. Adımlarınızı önceden planlamanıza izin verilir, ancak ilk adımınızı attığınızda planınızı değiştiremezsiniz. (Ve hiçbiri sarkma yok; onlar seni vuracaklar.)

Aniden, parlak bir fikir akla geliyor ...

Ah! Sadece sağa ve sola adım adım değiştirebilirsiniz! Sağ adım, sol adım, sağ adım, sol adım ve benzeri ...

Ah ah ah, çok hızlı değil. Dediğim gibi, işkenceci sadist. Her adımı mı, yoksa her ikinci adımı mı, yoksa her üçüncü adımı mı, vb. Bu yüzden, saf diziyi seçerseniz, RLRLRL...sizi başlatan her ikinci adımı atmaya zorlayabilirler LL. Uh ah! Sen en iyiler tarafından ısırılmışsın! Siyahlık senin üzerini sallar ve diğerleri kaybolur ...

Aslında hayır, daha ölmedin. Hala planınla gelmek zorundasın. Birkaç dakika düşündükten sonra, mahkum olduğunun farkındasın. Hayatta kalmanızı sağlayacak bir dizi adım planlamanın yolu yoktur. Bulabileceğin en iyi şey RLLRLRRLLRR. 1 Onbir adım ve daha fazlası. Onikinci adım ise R, İşkenceci her adımı atmanıza ve son üç adım sizi uçurumdan atmanıza neden olacaktır. Onikinci adım ise L, İşkenceci her üç adımı atmanızı sağlayacaktır ( LRLL), bu sizi engereklerin ve ölümcül ısırıklarının içine sokar.

RÖlümünüzü mümkün olduğu kadar geciktirmeyi umarak, on ikinci adım olarak seçim yaparsınız . Kulaklarınızda rüzgârla kükreyen, kendinizi merak ediyorsunuz ...

Ya üç adım attıysam?


Spoiler uyarısı!

Hala ölürsün. Görünüşe göre, kaç adım attıysanız olun, hangi seçimi yaparsanız yapın, Torturer'in ölümcül kaderinizi karşılamanızı sağlamak için seçebileceği bir dizi adımın olduğu bir nokta olacaktır. 2 Ancak, engerek ve uçurum üç adım uzakta olduğunda, toplam 1160 güvenli adım atabilirsiniz ve dört adım uzakta olduklarında, en az 13.000 güvenli adım olur! 3

Meydan okuma

Tek bir tamsayı verildiğinde , uçurumun ve engereklerin dört adım uzakta olduğunu varsayarak, n < 13000bir dizi ngüvenli adım çıktısı alın .

kurallar

  • Tam bir program veya bir işlev olabilir.
  • Giriş, STDIN veya eşdeğeri veya bir fonksiyon argümanı olarak alınabilir.
  • Çıkış olmalıdır iki farklı karakterler (olabilen +/-, R/L, 1/0vb.)
  • Çıktıdaki herhangi bir boşluk önemli değil.
  • Sabit kodlama bir çözüme izin verilmez. Bu, bu meydan okumayı önemsizleştirecektir.
  • Programınız (teoride) makul bir sürede bitmelidir. Gibi n=13000bir ay gibi sürebilir, ancak bin yıl veya daha fazla sürmemelidir. Yani kaba kuvvet yok. (En azından bundan kaçınmaya çalış .)
  • Yaşam bonusu: bir dizi 2000güvenli adım. Bunu yaparsanız, İşkenceci aziminiz, sebatınız ve yaşamanıza izin vereceğinden emin olmaktan çok etkilenecektir. Bu seferlik. (Bu sırayı ikili bir sayı olarak ele alın ve doğrulama için ondalık eşdeğeri sağlayın. Bu, cevapların çok uzun sürmesine izin verildiğinden hızlı bir şekilde biten cevapları ödüllendirmek içindir.)
  • Puan: Bonus kazanmaya hak kazanmazsanız, bayt - 0,75 ile çarpın .

Survive!


1 : Burada onun YouTube kanalında üzerinde, Numberphile James Grime yıldızlarından biri bu sorunu ve "çözüm" iyi bir açıklama yoktur https://www.youtube.com/watch?v=pFHsrCNtJu4 .

2 Erdoğan'ın uyuşmazlık sorunu olarak bilinen 80 yıllık bu varsayım, son zamanlarda Terence Tao tarafından kanıtlandı. İşte Quanta Dergisi'nde bu konuda çok güzel bir makale: https://www.quantamagazine.org/20151001-tao-erdos-discrepancy-problem/ .

3 Kaynak: Boris Konev ve Alexei Lisitsa tarafından yapılan, Erdoğan'ın Uyuşmazlık Konusunda Yapılan Anlaşmaya SAT Saldırısı . Buradan alındı: http://arxiv.org/pdf/1402.2184v2.pdf .


1
Öyleyse, bir çözüm yaparsam n=13000, ilk 2000 talimatı bir bonus kazanacak mı? Anlamsız görünüyor, bu yüzden muhtemelen başka bir şey demek istedin?
anatolyg

@anatolyg: Tüm çözümler teorik olarak n=13000bir yıl, belki on yıl içerisinde işlenebilmelidir . Bir ay bekleyecek n=2000misin? Muhtemelen hayır. Ve yaparsan , yine de bonusu hak ediyorsun.
El'endia Starman

Yanıtlar:


6

Java, 915 * 0,75 = 686,25

import java.util.*;class E implements Comparable<E>{static
int n,m,t,u;byte[]a;int k=2,b,d;E(){a=new byte[5];a[1]=13;}E(E
x){a=Arrays.copyOf(x.a,n+1);k=x.k;d=x.d;b=x.b;}int
g(int x){return(a[x]+1)%3-1;}void s(int x,int y){a[x]=(byte)(a[x]/3*3+(y+3)%3);}void
S(int x,int y){a[x]=(byte)(a[x]%3+(y+3)*3);}E
w(int x){if(g(k)==-x)return null;E e=new E(this);e.s(k,x);e.S(e.k++,x);for(m=0;++m<k;)if(k%m<1){u=e.a[m]/3-3+x;if(u==(k<9?2:4)*x)return
null;e.S(m,u);if(u==3*x){e.b++;if(k+m<=n){if(e.g(k+m)==x)return
null;e.s(k+m,-x);}}}return e;}public int compareTo(E o){m=d-o.d+(b-o.b)/60+(o.k-k)/150;return
m==0?o.k-k:m;}public static void main(String[]a){n=Integer.valueOf(a[0]);Queue<E>q=new PriorityQueue<>();q.add(new
E());for(;;){E x=q.remove(),y;if(x.k>n){for(t=0;++t<x.k;)System.out.print((x.g(t)+1)/2);return;}t=x.g(x.k<9?1:x.k%9==0?x.k/9:x.k%9);y=x.w(t);if(y!=null)q.add(y);y=x.w(-t);if(y!=null){y.d++;q.add(y);}}}}

Giriş, bir komut satırı argümanı olarak alınır.

Bu, neredeyse tüm olasılıkları deniyor (tek kısıtlama, ilk 8 adımın yalnızca -1.1 içinde geçmesi gerektiğidir), adım adım ilerleyerek, ilk denemek için hangi yolu kullanacağını seçmek için sihirli bir voodoo buluşması kullanarak.

(Oldukça hızlı) bilgisayarımda 2000 ve hatta 4000'i 1 saniye içinde çözüyor. Daha büyük sayılar için daha fazla RAM gerekir; 8GB'ta çözdüğüm en büyük giriş 5023'tür ve yaklaşık 30 saniye sürmüştür.

Bonus için talep edildiği şekilde, 2000 adım için çözümün ondalık gösterimi:

67629177464446960798008264442022667063957880432486338092706841703491740570274032860458934082821213021464065304260003487277917407152662394728833698812373924467640518368465012204980858438160127647802572983143425507448999967241207186701518207195015015739598846687434709056793597015487555707466358473564611432637890414593517116857771284711814076853125419306285869381974622557155019992727242896503018802441210966188045211779436703341152749688824296759097963388158731237092792251164105828728858516951458791084595247591674731645830905744761534078963607725435881491831508342871545788662307953494333833994658998

İkili haline geri dönüştürmek için CJam'deYb buna ekleyin .

Sezgisel yöntem hakkında: ilk önce kullandığım bir kalıp var: her 9 adımda ilk 9'u tekrarlamaya çalışır, her (9 * x) her adımda x'inci adımı tekrar etmeye çalışır. Bu benim python cevabımda indirdiğim ve kullandığım (hardkodlu) çözümden ilham alıyor.

Desenden sapma sayılarımı ve ayrıca "kenara" kaçtığımı (ölmekten 1 adım) takip ediyorum. Sezgisel işlev, temel olarak bu 2 sayının ve şimdiye kadar atılan adım sayısının ağırlıklı bir birleşimidir.

Sezgisel, hızı arttırmak için daha da ince olabilir ve buna rasgele bir faktör eklemenin birkaç yolu vardır.
Aslında, sadece bu problemle ilgili çarpımcı fonksiyonlar hakkında okudum ve önemli bir gelişme sağlayacak gibi görünüyor (TODO: bunu daha sonra uygulayın).

Ungolfed ve yorumladı:

import java.util.*;

public class Erdos implements Comparable<Erdos> {
    static int n; // input (requested number of steps)
    static int m, t, u; // auxiliary variables

    byte[] a; // keeps each step and sum combined into 1 byte
    int k = 2; // number of steps + 1 (steps are 1-based)
    int edge; // number of times we got to an edge
    int diff; // number of differences from the expected pattern

    // start with one step
    Erdos() {
        a = new byte[5];
        set(1, 1);
        setSum(1, 1);
    }

    // copy constructor
    Erdos(Erdos x) {
        a = Arrays.copyOf(x.a, n + 1);
        k = x.k;
        diff = x.diff;
        edge = x.edge;
    }

    // get the x'th step (can be -1, 0 or 1)
    int get(int x) {
        return (a[x] + 1) % 3 - 1;
    }

    // set the x'th step
    void set(int x, int y) {
        a[x] = (byte) (a[x] / 3 * 3 + (y + 3) % 3);
    }

    // get the sum of every x'th step (should be within -3..3)
    int getSum(int x) {
        return a[x] / 3 - 3;
    }

    // set the sum of every x'th step
    void setSum(int x, int y) {
        a[x] = (byte) (a[x] % 3 + (y + 3) * 3);
    }

    // try to add a step with value x (1 or -1)
    Erdos grow(int x) {
        if (get(k) == -x) // predetermined step doesn't match
            return null;
        Erdos e = new Erdos(this);
        e.set(k, x);
        e.setSum(e.k++, x);
        for (m = 0; ++m < k;)
            if (k % m < 1) { // check all divisors of k
                u = e.getSum(m) + x; // updated sum
                if (u == (k < 9 ? 2 : 4) * x) // use limit 2 for the first 8 steps, 4 for the rest
                    return null; // dead
                e.setSum(m, u);
                if (u == 3 * x) { // we're at an edge
                    e.edge++;
                    if (k + m <= n) { // predetermine future step - should be going back
                        if (e.get(k + m) == x) // conflict
                            return null;
                        e.set(k + m, -x);
                    }
                }
            }
        return e;
    }

    public int compareTo(Erdos o) { // heuristic function
        m = diff - o.diff + (edge - o.edge) / 60 + (o.k - k) / 150;
        return m == 0 ? o.k - k : m;
    }

    public static void main(String[] a) {
        n = Integer.valueOf(a[0]);
        Queue<Erdos> q = new PriorityQueue<>();
        q.add(new Erdos());
        for (;;) {
            Erdos x = q.remove(), y;
            if (x.k > n) { // we made it
                for (t = 0; ++t < x.k;)
                    System.out.print((x.get(t) + 1) / 2);
                return;
            }
            t = x.get(x.k < 9 ? 1 : x.k % 9 == 0 ? x.k / 9 : x.k % 9); // next step based on the pattern
            y = x.grow(t);
            if (y != null)
                q.add(y);
            y = x.grow(-t);
            if (y != null) {
                y.diff++;
                q.add(y);
            }
        }
    }
}

"later" bir yıldan fazla bekler
CalculatorFeline

1

Python 2,236 bayt

n=input();r=len;u=[("",[0]*(n//4))]
while n>r(u[-1][0]):
 y,t=u.pop()
 for c in 0,1:
  s=t[:];u+=(y+"LR"[c],s),
  for i in range(r(s)):
   if-~r(y)//-~i*-~i==-~r(y):s[i]+=2*c-1;
   if abs(s[i])>3:u.pop();break;
print(u[-1][0])

Bu, kaba kuvvet kuvvet yöntemi için n = 223 için yalnızca birkaç saniye süren, ancak n> = 224 için çok daha uzun süren oldukça hızlıdır.

Açıklama: u [i] dizgideki her adımı takip ettikten sonra geçerli konum olacak şekilde dizgi listesi çiftlerinin (s, u) listesini takip edin. Listedeki her dize için "L" veya "R" eklemeye çalışın, ardından kesişen listedeki değerleri değiştirin. (yani sonuçta elde edilen dize uzunluğu 10 ise, taşıdığınız yönlere göre 1, 1,2 ve 10 konumlarından 1 ekleyin veya çıkarın). 3 veya -3'ü aşarsanız, yeni çifti uzaklaştırın, aksi halde listede tutun. En uzun dizeler sonunda tutulur. Bir uzunluk n uzunluğunuz olduğunda, onu geri getirin.


Neden python 2/3?
21

Her ikisinde de aynı şekilde çalışır. Onlardan birini belirtmeli miyim?
fricative Kavun

Muhtemelen yapmalısın. Sadece merak ettim çünkü bunun //python 2 ile elde edilebileceğini bilmiyordum .
Rɪᴋᴇʀ

-2

Python 2,729 bayt

n=0
for x in"eJytVU2LwyAQPWzTvZjjspcsxFYTBdNuQSEF+///1jp+p5o0hYVSBl9nfOObNz1MlAgqzMcEEwQkDyIkFpDYCW0UnChbyZJiK2sfhDcYmu9hT0GdIPQvLduAmoCvvqEssvq84CVCpLzrNcOOspLhY6/KswB6FmoSxGPBcWts7lsMp/0q83da1hgC6k7GoqBir1ruAFIVvWIdTi++oGIAyZw8mkuG03uDDc+rEsSWTmFBwbLgtTF8hl1e/lpCigR7+pM5V9lIqVJBjStzKNRRQDp6UOrvwga6VFrGcWz6YHwLNYWUYeZfWO/DQTq7i4dAxixeszmtFEw7Cr5v9R3lRVF55TDzY6QRrSfzF9NLE7lAZ+vLnGgYLZ/FlCuoRcOugeFduHTqRWmyh1J91XpIndIbEk8jifL8hs8qQ8vjAVoGqhK5Tm/O5svpXd82QH4Azq05kYnhj93PzLbcTisFzXWfDqIC5zsq3jU7UUhSh1R3L4+i4HCXKlrGyywSBttPr2zpL4gCDPtk2HPN5tgZFomzSDPfGAlASus+e4KlLcjS0vPQ0f5/mR/r1s4PcxsgMLRSMp617AveCuup2OCAPBT6yltWrPO9azsbp6fphR87Lc7VzcbEt5F4Ydg/NzhXTA==".decode("base64").decode("zip"):n=n*64+ord(x)
print bin(n)[2:input()+2]

Bence bu, “çabucak biten cevapları ödüllendirmek” fikriyse, bu bonusu hak ediyor.

Bununla birlikte, bu, zorunluluk ruhu içinde olmayan, kodlanmış bir cevaptır (yazdığımda açıkça reddedilmese de).


2
Sonunda bir cevap! d ;-)
wizzwizz4
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.