Bak ve söyle: Conway yeniden ziyaret edildi


16

Hepiniz aşina olmalıdır Conway dizisi (aka 'görünüm ve say'-dizisi) artık:

     1
    11
    21
  1211
111221
312211
etc

Ayrıca başlangıç ​​noktası olarak herhangi bir rasgele sayı ile başlayabilirsiniz. Izin vermek f(s)dizinin bir sonraki elemanı olmak. Şimdi her verilen için sbulabiliriz f(s). Ters önemsiz olarak değil: Her için değil yolası selefi bulmak söyle f(s) = y. Mesela y = 1bir selefi bulamıyoruz. Ancak y, eşit bir uzunluğa sahipse , bunu bir öncünün her bir parçasını tanımlayan basamak çiftlerine bölebilirsiniz:

513211 divides in 51,32,11
so: 51 comes from 11111 
    32 comes from 222
    11 comes from 1
put together: 111112221

Böylece bu şekilde her bir uzunluk için benzersiz bir öncülü tanımlayabiliriz y.

Not : sBu şekilde tanımlanan 'selefi' genellikle tatmin edici DEĞİLDİR f(s) = y.

Hedef

Bir basamak dizesini giriş olarak kabul eden bir işlev / program snippet'i yazın.

  • giriş dizisinin uzunluğu ise Conway sekansının bir sonraki elemanı hesaplar tek
  • giriş dizi uzunluğu ise, yukarıda tarif edildiği gibi, giriş dizesi selefi hesaplar bile .

Bayt cinsinden en kısa kod kazanır.

Bak ve söyle dizilerine dayanan Son Sorular:


1
Kafam karıştı. Nasıl açıklayabilir 513111içine ayırır 51, 32ve 11?
14:44

1
Bu bazı bak ve söyle dizi meydan okuma ve bir çalışma uzunluğu kod çözme meydan kombine bir kopyası gibi hissediyorum (eminim biz bunları vardı).
Martin Ender

3
Selefi ne olurdu 11111111111111? Özelliklerine göre, olurdu 1111111. Bunun için makul bir cevap tanımlamak üzere şartnamenizi değiştirmelisiniz.
TheNumberOne

1
@TheBestOne 11111111111111sadece selefi yok. Bu geçersiz bir girdi.
kay

2
@TheBestOne Evet bu doğru, selef için her zaman 'gerçek' selef ile eşleşmeyen rastgele bir kural tanımladım.
Kusur

Yanıtlar:



5

Yakut, 125 120119 101 bayt

f=->n{c=n.chars;(n.size%2>0?c.chunk{|x|x}.map{|a,b|[b.size,a]}:c.each_slice(2).map{|a,b|b*a.hex})*''}

İşlev aracılığıyla alınan dize girişi f:

f['111221']    # => "1211"
f['513211']    # => "111112221"
f['111112221'] # => "513211"

Notlarla genişletilmiş:

# define lambda that takes one arg
f = -> (n) {
  # store digits in c
  c = n.chars

  # n is of odd length
  if n.size % 2 > 0
    # group identical numbers
    c.chunk{ |x| x }.map do |a, b|
      # array of [digit count, digit value]
      [b.size, a]
    end
  else
    # slice array into groups of two elements
    c.each_slice(2).map do |a, b|
      # repeat the second digit in a pair
      # the first digit-times.
      b * a.hex
    end
  end * '' # join array
}

4

Prolog - 170 bayt

[]/[].
T/R:-0*_*T*R.
C*X*[X|T]*R:-(C+1)*X*T*R.
C*X*T*Y:-10*C+X+Y+R,T/R.
N+R+A:-N=:=0,A=R;D is N mod 10,N//10+R+[D|A].
F-C-R:-C/N,(N=F,R=C;F-N-R).
[1]-[1,1]. S-T:-S-[1]-T.

Bu ekran alıntısı işlevi tanımlar (-)/2. Şöyle çağırabilirsiniz

?- [1,1,1,3,2,1,3,2,1,1]-T.
T = [1, 3, 1, 1, 2, 2, 2, 1] .

?- [1]-T.
T = [1, 1] .

Bu dizide garip bir pariteye sahip tek bir uzunluk var gibi görünüyor : ilk [1].

wr_len :- wr_len(1, [1]).
wr_len(N, Cur) :-
    length(Cur, Len),
    TrailingZeroes is lsb(Len),
    (TrailingZeroes > 0 -> Par = 'even'; Par = 'odd'),
    writef('%t\t%t\t%t\t%t\n', [N, Len, Par, TrailingZeroes]),
    get_next(Cur, Next),
    succ(N, O),
    !, wr_len(O, Next).
% index, length, parity of length, num of trailing 0 in bin presentation of length
?- wr_len.
1       1       odd     0
2       2       even    1
3       2       even    1
4       4       even    2
5       6       even    1
6       6       even    1
7       8       even    3
8       10      even    1
9       14      even    1
10      20      even    2
11      26      even    1
12      34      even    1
13      46      even    1
14      62      even    1
15      78      even    1
16      102     even    1
17      134     even    1
18      176     even    4
19      226     even    1
20      302     even    1
21      408     even    3
22      528     even    4
23      678     even    1
24      904     even    3
25      1182    even    1
26      1540    even    2
27      2012    even    2
28      2606    even    1
29      3410    even    1
30      4462    even    1
31      5808    even    4
32      7586    even    1
33      9898    even    1
34      12884   even    2
35      16774   even    1
36      21890   even    1
37      28528   even    4
38      37158   even    1
39      48410   even    1
40      63138   even    1
41      82350   even    1
42      107312  even    4
43      139984  even    4
44      182376  even    3
45      237746  even    1
46      310036  even    2
47      403966  even    1
48      526646  even    1
49      686646  even    1
50      894810  even    1
51      1166642 even    1
52      1520986 even    1
53      1982710 even    1
54      2584304 even    4
55      3369156 even    2
56      4391702 even    1
57      5724486 even    1
58      7462860 even    2
59      9727930 even    1
ERROR: Out of global stack
% I added a few "strategic" cuts (`!`) to get so far.

Okunabilir:

get_next([], []).
get_next(Current, Next) :-
    get_next_sub(0, _, Current, Next).

get_next_sub(Length, Digit, [Digit|Tail], Result) :-
    get_next_sub(Length+1, Digit, Tail, Result).
get_next_sub(Length, Digit, Further, Result) :-
    number_to_list(10*Length+Digit, Result, ResultTail),
    get_next(Further, ResultTail).

number_to_list(Number, Result, Accumulator) :-
    0 is Number -> Result = Accumulator;
    Digit is Number mod 10,
    number_to_list(Number // 10, Result, [Digit|Accumulator]).

get_previous(Stop, Current, Result) :-
    get_next(Current, Next),
    (   Next = Stop
    ->  Result = Current
    ;   get_previous(Stop, Next, Result)
    ).

get_prev_or_next(Input, Result) :-
    length(Input, Length),
    (   1 is Length mod 2
    ->  get_next(Input, Result)
    ;   get_previous(Input, [1], Result)
    ).

3

Python: 139 karakter

import re
f=lambda s:''.join(['len(b)'+a for a,b in re.findall(r'((\d)\2*)',s)] if len(s)%2 else map(lambda a,b:b*int(a),s[::2],s[1::2]))

tek test çantası

print f('1111122221111222112')
>>> 514241322112
print f('514241322112')
>>> 1111122221111222112

Şunlar arasından boşluğu kaldırabilirsiniz s)] ifiçin s)]if.
Bakuriu

2 else
Beta Çürüme

3

Haskell, 134128 115

n=length
l x=x#mod(n x)2
(a:b:c)#0=replicate(read[a])b++c#0
(a:b)#1=(\(c,d)->show(1+n c)++a:d#1)$span(==a)b
_#_=[]

O Stdin / Stdout'a uzakta olmak gerekirse, ekleme main=interact liçin 150 144 131 toplam karakter. İşlev çağrılır l.

*Main> putStr . unlines $ map (\x->x++":\t"++l x) ([replicate n '1'|n<-[5..10]]++map show [0,6..30]++map show [n*n+n|n<-[2..10]])
11111:  51
111111: 111
1111111:    71
11111111:   1111
111111111:  91
1111111111: 11111
0:  10
6:  16
12: 2
18: 8
24: 44
30: 000
6:  16
12: 2
20: 00
30: 000
42: 2222
56: 66666
72: 2222222
90: 000000000
110:    2110

Lütfen kullanım örneği verebilir misiniz? Bende iken l "11"işe, ben bir istisna olsun l "111"veyal "1111111111111"
Paul Guyot

@PaulGuyot, Puanımdan birkaç karakter kesen düzeltmek gibi görünüyor. Teşekkürler :-)
Zaq

3

Perl - 98 bayt

Tüm bu kontrol ifadelerinin boyutu beni rahatsız ediyor, ancak normal ifadelerin nasıl çalıştığından oldukça memnunum.

($_)=@ARGV;if(length()%2){$\=$&,s/^$&+//,print length$&while/^./}else{print$2x$1while s/^(.)(.)//}

sıkıştırılmamış:

($_)=@ARGV;
if(length()%2)
{
$\=$&, #Assigning the character to $\ causes it to be appended to the print (thanks, tips thread!)
s/^$&+//, #Extract the string of characters
print length$& #Print its length
while/^./ #Get next character into $&
}else{
print$2x$1
while s/^(.)(.)//
}

2

Erlang, 205

f(L)->g(L,L,[]).
g([A,B|T],L,C)->g(T,L,lists:duplicate(A-$0,B)++C);g([],_,R)->R;g(_,L,_)->i(L,[]).
h([A|T],A,N,B)->h(T,A,N+1,B);h(L,B,N,C)->i(L,integer_to_list(N)++[B|C]).
i([H|T],A)->h(T,H,1,A);i(_,R)->R.

Ana işlev f, girdiyi bir Erlang dizgisi olarak almak ve çıktıyı bir dizge olarak döndürmektir.

f("11"). % returns "1"
f("111"). % returns "31"
f("1111111111111"). % returns "131"

İşlev, 9'dan fazla aynı karakter büyük / küçük harf gereksinimi düşürülerek 15 bayt daha kısa (190) yapılabilir. fçağrılar gyinelemeli selefi hesaplar ve karakter sayısı tek ise (zaman hesaplama uçta bulunan), bu işlevini çağırır iile eşleştirilmiş, hbir sonraki eleman hesaplar.


2

Haskell, 105

import Data.List
l=length
c r|odd$l r=group r>>=(l>>=(.take 1).shows)|x:y:z<-r=[y|_<-['1'..x]]++c z|0<1=r

Ben herhangi bir yardımcı işlevleri kullanarak değil ortaya çıktı güzel :-) düşünüyorum.


|x:y:z<-r- Bunu yapabileceğini tamamen bilmiyordum. Çok havalı!
Flonk

@Flonk "Desen korumaları" olarak adlandırılır. Eskiden bir
uzantıydı

Bu, birçok şeyi çok daha kolay hale getirir. Her gün yeni bir şeyler öğreniyorsun! :)
Flonk

2

APL (45)

∊{2|⍴⍵:(⊃,⍨⍕∘⍴)¨⍵⊂⍨1,2≠/⍵⋄/⍨∘⍎/¨⌽¨⍵⊂⍨1 0⍴⍨⍴⍵}

Evet, bu dışarıda olsa bile geçerli bir işlev tanımıdır .

      ∊{2|⍴⍵:(⊃,⍨⍕∘⍴)¨⍵⊂⍨1,2≠/⍵⋄/⍨∘⍎/¨⌽¨⍵⊂⍨1 0⍴⍨⍴⍵}'513211'
111112221
      ∊{2|⍴⍵:(⊃,⍨⍕∘⍴)¨⍵⊂⍨1,2≠/⍵⋄/⍨∘⍎/¨⌽¨⍵⊂⍨1 0⍴⍨⍴⍵}'111112221'
513211
      f←∊{2|⍴⍵:(⊃,⍨⍕∘⍴)¨⍵⊂⍨1,2≠/⍵⋄/⍨∘⍎/¨⌽¨⍵⊂⍨1 0⍴⍨⍴⍵}
      f ¨ '513211' '111112221'
┌─────────┬──────┐
│111112221│513211│
└─────────┴──────┘

2

Java 7, Puan = 252 235 bayt

Evet, yine java; dünyanın en kötü golf dili. Bu yaklaşım dizeleri kullanır. Java'da keyfi olarak büyük tamsayılar desteklenir, ancak kodlanması çok daha fazla zaman alır.

İle arayın f(intputString). İlgili dizeyi döndürür.

golfed:

String f(String a){char[]b=a.toCharArray();a="";int i=0,j=0,d=0,e=b.length;if(e%2==0)for(;i<e;i+=2)for(j=0;j<b[i]-48;j++)a+=b[i+1];else{for(;i<e;i++)d=d==0?(j=b[i]-48)*0+1:b[i]-48!=j?(a+=d+""+j).length()*--i*0:d+1;a+=d;a+=j;}return a;}

Golf Yapı kodu ile genişletilmiş:

public class LookAndSayExpandedGolfed{

    public static void main(String[] args){
        System.out.println(new LookAndSayExpandedGolfed().f(args[0]));
    }

    String f(String a){
        char[]b=a.toCharArray();
        a="";
        int i=0,j=0,d=0,e=b.length;
        if(e%2==0)
            for(;i<e;i+=2)
                for(j=0;j<b[i]-48;j++)
                    a+=b[i+1];
        else{
            for(;i<e;i++)
                d=d==0?(j=b[i]-48)*0+1:b[i]-48!=j?(a+=d+""+j).length()*--i*0:d+1;
            a+=d;
            a+=j;
        }
        return a;
    }

}

Kısmen Golf:

public class LookAndSayPartiallyGolfed{

    public static void main(String[] args){
        System.out.println(new LookAndSayPartiallyGolfed().f(args[0]));
    }

    String f(String a){
        char[] number = a.toCharArray();
        String answer = "";
        int i, j, longestStreakLength = 0;
        if (number.length % 2 == 0){
            for (i = 0; i < number.length; i += 2)
                for (j = 0; j < number[i] - 48; j++)
                    answer += number[i+1];
        } else{
            j = 0;
            for (i = 0; i < number.length; i++)
                longestStreakLength = longestStreakLength == 0 ? (j = number[i] - 48) * 0 + 1 : number[i] - 48 != j ? (answer += longestStreakLength + "" + j).length()*--i*0 : longestStreakLength + 1;
            answer += longestStreakLength;
            answer += j;
        }
        return answer;
    }

}

Tamamen genişletildi:

public class LookAndSay{

    public static void main(String[] args){
        System.out.println(new LookAndSay().function(args[0]));
    }

    String function(String a){
        char[] number = a.toCharArray();
        if (number.length % 2 == 0){
            String answer = "";
            for (int i = 0; i < number.length; i += 2){
                for (int j = 0; j < number[i] - '0'; j++){
                    answer += number[i+1];
                }
            }
            return answer;
        }
        String answer = "";
        int longestStreakLength = 0;
        int longestStreakNum = 0;
        for (int i = 0; i < number.length; i++){
            if (longestStreakLength == 0){
                longestStreakNum = number[i] - '0';
                longestStreakLength = 1;
                continue;
            }
            if (number[i] - '0' != longestStreakNum){
                answer += longestStreakLength;
                answer += longestStreakNum;
                longestStreakLength = 0;
                i--;
            } else {
                longestStreakLength++;
            }
        }
        answer += longestStreakLength;
        answer += longestStreakNum;
        return answer;
    }

}

Çalıştırmak için önce ikinci girdiyi derleyin: javac LookAndSayExpandedGolfed.java

Sonra ile çalıştırın: java LookAndSayExpandedGolfed

Düzenleme: Sabit hata.


Benim için çalışmıyor,Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4 at java.lang.String.charAt(String.java:658)
Octavia Togami

@KenzieTogami Düzeltildi.
TheNumberOne

Öyle, sanmıyorum --1olması gerekiyordu --i?
Octavia Togami

@KenzieTogamie Evet, öyle. Şimdi düzeltildi.
TheNumberOne

Harika, işe yarıyor. Ancak ters çevirici başarısız olur. 513211-> 11111.
Octavia Togami

1

Javascript (tarayıcı içi, ES5, IE8 +), 152

var s=prompt(),r='',n=r,c=r,i=0;do{c!=s[i]?(r+=n+c,n=1,c=s[i]):n++;i++}while(c)n='';i=0;while(s[i]){n+=Array(1*s[i]+1).join(c=s[i+1]);i+=2}alert(c?n:r)

Eğer var atlarsanız 4 karakter veya diğer orta değişmemiş globaller ile birkaç karakter daha kısaltılabilir, ancak bir dakika boyunca kötü programcı değiliz gibi davranalım.

Sorgu kullanmak yerine argüman ve dönüş değeri ile ES6 kısa sözdizimi işlevine geçmek, IO için uyarı daha fazla tasarruf sağlayabilir.

JSBurada: http://jsfiddle.net/86L1w6Lk/


5
Bunlar için endiţelenme var... hepimiz burada "kötü programcýyýz". ;)
Martin Ender

1

Python 3- 159 bayt

import re;l=input();x=len;print(''.join([str(x(i))+j for i,j in re.findall('((.)\2*)',l)]if x(l)%2 else[j*int(i)for i,j in[l[i:i+2]for i in range(0,x(l),2)]]))

1

Kobra - 217

(186, eğer başka bir yerde var olduğu useiçin bir ifade varsayabilirim System.Text.RegularExpressions)

do(s='')=if((l=s.length)%2,System.Text.RegularExpressions.Regex.replace(s,(for x in 10 get'[x]+|').join(''),do(m=Match())="['[m]'.length]"+'[m]'[:1]),(for x in 0:l:2get'[s[x+1]]'.repeat(int.parse('[s[x]]'))).join(''))

1

JavaScript (ES6) 85

Normal ifadeyi kullanarak işlevle değiştirin. Giriş uzunluğunun çift veya tek olmasına bağlı olarak farklı normal ifade ve farklı işlev.

F=s=>s.replace((i=s.length&1)?/(.)(\1*)/g:/../g,x=>i?x.length+x[0]:x[1].repeat(x[0]))
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.