Lihat-dan-katakan: Conway ditinjau kembali

16

Anda semua harus terbiasa dengan urutan Conway (alias 'look-and-say'-sequence) sekarang:

     1
    11
    21
  1211
111221
312211
etc

Anda juga dapat memulai dengan nomor acak sebagai titik awal. Membiarkan f(s)menjadi elemen berikutnya dari urutan. Sekarang untuk setiap yang skita dapat temukan f(s). Kebalikannya tidak sepele: tidak untuk setiap ykemungkinan menemukan pendahulunya sseperti itu f(s) = y. Misalnya untuk y = 1kita tidak dapat menemukan pendahulunya. Tetapi jika ymemiliki panjang genap, Anda dapat membaginya menjadi pasangan digit yang menggambarkan masing-masing bagian dari pendahulunya:

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

Jadi dengan cara ini kita dapat mendefinisikan pendahulu unik untuk setiap ypanjang genap.

Catatan : 'Pendahulu' yang sdidefinisikan dengan cara ini umumnya TIDAK memuaskan f(s) = y.

Tujuan

Tuliskan potongan fungsi / program yang menerima serangkaian digit sebagai inputnya

  • menghitung elemen berikutnya dari urutan Conway jika panjang string input ganjil
  • menghitung pendahulu dari string input seperti yang didefinisikan di atas jika panjang string input adalah genap .

Kode terpendek dalam byte menang.

Pertanyaan terbaru berdasarkan urutan tampilan dan katakan:

cacat
sumber
1
Saya bingung. Bisakah Anda menjelaskan bagaimana 513111membaginya menjadi 51, 32dan 11?
ossifrage mual
1
Saya merasa seperti ini adalah duplikat gabungan dari beberapa tampilan dan mengatakan tantangan urutan dan tantangan pendekodean run-length (saya yakin kita punya itu).
Martin Ender
3
Seperti apa pendahulunya 11111111111111? Menurut spec Anda, itu akan menjadi 1111111. Anda harus memodifikasi spesifikasi Anda untuk menentukan jawaban yang masuk akal untuk ini.
TheNumberOne
1
@TheBestOne 11111111111111tidak memiliki pendahulu. Ini input ilegal.
kay
2
@TheBestOne Ya ini benar, saya menetapkan aturan arbitrer untuk pendahulunya yang tidak selalu cocok dengan pendahulu 'nyata'.
flawr

Jawaban:

3

CJam, 46 45 44 43 42 byte

l_,2%{0\{@)@@_2$=!{0\0}*;}*\)\}{2/{(~*}%}?

Uji di sini. Dibutuhkan nomor pada STDIN dan mencetak hasilnya ke STDOUT.

Martin Ender
sumber
si-> ~= 45
Pengoptimal
@Optimizer Terima kasih, saya lupa Anda dapat mengevaluasi karakter.
Martin Ender
5

Rubi, 125 120 119 101 byte

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})*''}

Input string diambil melalui fungsi f:

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

Diperluas dengan catatan:

# 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
}
Agustus
sumber
4

Prolog - 170 byte

[]/[].
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.

Potongan ini mendefinisikan fungsi (-)/2. Anda bisa memintanya seperti

?- [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] .

Tampaknya hanya ada satu panjang dalam urutan ini dengan paritas aneh: awal [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.

Dapat dibaca:

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)
    ).
kay
sumber
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]))

kasus uji tunggal

print f('1111122221111222112')
>>> 514241322112
print f('514241322112')
>>> 1111122221111222112
averykhoo
sumber
Anda dapat menghapus ruang dari s)] ifhingga s)]if.
Bakuriu
Anda juga dapat menghapus ruang di antara2 else
Beta Decay
3

Haskell, 134 128 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
_#_=[]

Jika perlu dari stdin / stdout, menambahkan main=interact luntuk 150 144 131 Total chars. Fungsi ini disebut 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
Zaq
sumber
Bisakah Anda berikan contoh penggunaan? Ketika saya mulai l "11"bekerja, saya mendapatkan pengecualian dengan l "111"ataul "1111111111111"
Paul Guyot
@ PaulGuyot, Sepertinya memperbaiki yang memotong beberapa karakter dari skor saya. Terima kasih :-)
Zaq
3

Perl - 98 byte

Ukuran semua pernyataan kontrol ini mengganggu saya, tapi saya cukup senang dengan bagaimana regex bekerja.

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

Terkompresi:

($_)=@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/^(.)(.)//
}
BMac
sumber
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.

Fungsi utamanya adalah f, mengambil input sebagai string Erlang dan mengembalikan output sebagai string juga.

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

Fungsi ini dapat dibuat lebih pendek 15 byte (190) dengan menjatuhkan lebih dari 9 persyaratan huruf identik. fpanggilan gyang menghitung pendahulunya secara rekursif, dan jika jumlah karakter ganjil (ditemukan pada saat perhitungan berakhir), ia memanggil fungsi iyang, dipasangkan dengan h, menghitung elemen berikutnya.

Paul Guyot
sumber
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

Saya pikir itu bagus ternyata tidak menggunakan fungsi pembantu :-).

haskeller bangga
sumber
|x:y:z<-r- Saya benar-benar tidak tahu Anda bisa melakukan itu. Itu sangat keren!
Flonk
@Flonk Ini disebut "penjaga pola". Dulu ekstensi dan dalam salah satu versi Haskell ditambahkan :-)
bangga haskeller
Ini membuat banyak hal jadi lebih mudah. Anda belajar sesuatu yang baru setiap hari! :)
Flonk
2

APL (45)

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

Ya, itu definisi fungsi yang valid, bahkan dengan di luar.

      ∊{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│
└─────────┴──────┘
marinus
sumber
2

Java 7, Skor = 252 235 byte

Yap, ini java lagi; bahasa golf terburuk di dunia. Pendekatan ini menggunakan string. Bilangan bulat yang sewenang-wenang didukung di java tetapi akan membutuhkan lebih banyak ruang untuk kode

Panggil dengan f(intputString). Mengembalikan string yang sesuai.

Golf:

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 Diperluas dengan kode struktur:

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;
    }

}

Golf Sebagian:

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;
    }

}

Benar-benar diperluas:

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;
    }

}

Untuk menjalankan, kompilasi pertama entri kedua dengan: javac LookAndSayExpandedGolfed.java

Kemudian jalankan dengan: java LookAndSayExpandedGolfed

Sunting: Memperbaiki kesalahan.

TheNumberOne
sumber
Tidak bekerja untuk saya,Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4 at java.lang.String.charAt(String.java:658)
Octavia Togami
@KenzieTogami Diperbaiki.
TheNumberOne
Kurasa tidak, --1seharusnya begitu --i?
Octavia Togami
@KenzieTogamie Ya, benar. Sudah diperbaiki sekarang.
TheNumberOne
Keren, itu berhasil. Namun, pembalik gagal. 513211-> 11111.
Octavia Togami
1

Javascript (di browser, 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)

Dapat diperpendek oleh 4 karakter jika Anda melewatkan var, atau beberapa karakter lagi dengan global yang tidak terdidik menengah lainnya juga, tapi mari kita berpura-pura kita bukan programmer yang buruk selama satu menit.

Beralih ke fungsi sintaks pendek ES6 dengan argumen dan mengembalikan nilai alih-alih menggunakan prompt, peringatan untuk IO dapat menyimpan lebih banyak.

JSFiddle di sini: http://jsfiddle.net/86L1w6Lk/

pengguna33068
sumber
5
Jangan khawatir tentang varitu ... kita semua "programmer buruk" di sini. ;)
Martin Ender
1

Python 3 - 159 byte

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)]]))
Peluruhan Beta
sumber
1

Cobra - 217

(186 jika saya dapat menganggap usepernyataan System.Text.RegularExpressionsada di tempat lain)

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(''))
Suram
sumber
1

JavaScript (ES6) 85

Menggunakan ekspresi reguler ganti dengan fungsi. Regexp berbeda dan fungsi berbeda tergantung pada panjang input yang genap atau ganjil.

F=s=>s.replace((i=s.length&1)?/(.)(\1*)/g:/../g,x=>i?x.length+x[0]:x[1].repeat(x[0]))
edc65
sumber