Nhìn và nói: Xem lại Conway


16

Bây giờ, tất cả bạn nên làm quen với trình tự Conway (hay còn gọi là trình tự nhìn và nói) :

     1
    11
    21
  1211
111221
312211
etc

Bạn cũng có thể bắt đầu bằng bất kỳ số tùy ý nào làm điểm bắt đầu. Hãy f(s)là yếu tố tiếp theo của chuỗi. Bây giờ cho mỗi cho schúng ta có thể tìm thấy f(s). Điều ngược lại không tầm thường: không phải ai cũng ycó thể tìm được người tiền nhiệm snhư vậy f(s) = y. Ví dụ, y = 1chúng ta không thể tìm thấy một người tiền nhiệm. Nhưng nếu ycó độ dài chẵn, bạn có thể chia nó thành các cặp chữ số mô tả từng phần của tiền thân:

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

Vì vậy, theo cách này, chúng ta có thể định nghĩa một người tiền nhiệm duy nhất cho mỗi ychiều dài chẵn.

Lưu ý : 'người tiền nhiệm' sđược định nghĩa theo cách này thường KHÔNG thỏa mãn f(s) = y.

Mục tiêu

Viết đoạn mã chức năng / chương trình chấp nhận một chuỗi các chữ số làm đầu vào

  • tính toán phần tử tiếp theo của chuỗi Conway nếu độ dài của chuỗi đầu vào là số lẻ
  • tính toán tiền thân của chuỗi đầu vào như được xác định ở trên nếu độ dài chuỗi đầu vào là chẵn .

Mã ngắn nhất trong byte thắng.

Các câu hỏi gần đây dựa trên trình tự nhìn và nói:


1
Tôi bối rối. Bạn có thể giải thích làm thế nào 513111chia thành 51, 3211?
squossish ossifrage

1
Tôi cảm thấy như đây là một bản sao kết hợp của một số thử thách nhìn và nói chuỗi và thử thách giải mã độ dài chạy (tôi chắc chắn chúng ta đã có những thử thách đó).
Martin Ender

3
Người tiền nhiệm 11111111111111sẽ là gì? Theo thông số kỹ thuật của bạn, nó sẽ được 1111111. Bạn nên sửa đổi đặc điểm kỹ thuật của bạn để xác định một câu trả lời hợp lý cho việc này.
TheNumberOne

1
@TheBestOne 11111111111111đơn giản là không có người tiền nhiệm. Đó là một đầu vào bất hợp pháp.
kay

2
@TheBestOne Vâng, điều này đúng, tôi đã xác định một quy tắc tùy ý cho người tiền nhiệm không phải lúc nào cũng khớp với người tiền nhiệm 'thực'.
flawr

Câu trả lời:



5

Hồng ngọc 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})*''}

Chuỗi đầu vào được thực hiện thông qua chức năng f:

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

Mở rộng với ghi chú:

# 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 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.

Snipped này xác định chức năng (-)/2. Bạn có thể gọi nó như

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

Dường như chỉ có một độ dài trong chuỗi này với một tính chẵn lẻ: chữ cái đầu tiên [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.

Có thể đọc được

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 ký tự

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]))

trường hợp thử nghiệm duy nhất

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

Bạn có thể loại bỏ không gian từ s)] ifđến s)]if.
Bakuriu

Bạn cũng có thể xóa khoảng trống ở giữa2 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
_#_=[]

Nếu nó cần phải được từ stdin / stdout, thêm main=interact lcho 150 144 131 tổng số ký tự. Hàm được gọi 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

Bạn có thể vui lòng cung cấp ví dụ sử dụng? Trong khi tôi đi l "11"làm, tôi có một ngoại lệ với l "111"hoặcl "1111111111111"
Paul Guyot

@PaulGuyot, Có vẻ như sửa chữa mà cắt một vài ký tự khỏi điểm số của tôi. Cảm ơn :-)
Zaq

3

Perl - 98 byte

Kích thước của tất cả các câu lệnh kiểm soát này làm tôi khó chịu, nhưng tôi khá hài lòng với cách các biểu thức chính thức hoạt động.

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

Không nén

($_)=@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.

Hàm chính là f, lấy đầu vào là một chuỗi Erlang và cũng trả lại đầu ra dưới dạng một chuỗi.

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

Hàm có thể được thực hiện ngắn hơn 15 byte (190) bằng cách bỏ hơn 9 yêu cầu trường hợp ký tự giống hệt nhau. fcác cuộc gọi gtính toán đệ quy trước và nếu số lượng ký tự là số lẻ (được tìm thấy khi tính toán kết thúc), nó gọi hàm i, được ghép nối với h, tính toán phần tử tiếp theo.


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

Tôi nghĩ thật tuyệt khi nó không sử dụng bất kỳ chức năng trợ giúp nào :-).


|x:y:z<-r- Tôi hoàn toàn không biết bạn có thể làm điều đó. Thú vị thật!
Flonk

@Flonk Nó được gọi là "mẫu bảo vệ". Nó từng là một phần mở rộng và trong một trong các phiên bản của Haskell, nó đã được thêm vào :-)
tự hào

Điều này làm cho rất nhiều thứ dễ dàng hơn nhiều. Bạn học được điều gì mới mỗi ngày! :)
Flonk

2

APL (45)

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

Vâng, đó là một định nghĩa hàm hợp lệ, ngay cả với bên ngoài.

      ∊{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, Điểm = 252 235 byte

Đúng, đó là java một lần nữa; ngôn ngữ golf tồi tệ nhất trên thế giới. Cách tiếp cận này sử dụng chuỗi. Các số nguyên lớn tùy ý được hỗ trợ trong java nhưng sẽ tốn nhiều chỗ hơn để mã hóa.

Gọi với f(intputString). Trả về chuỗi tương ứng.

Chơi gôn

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

Golfed Mở rộng với mã cấu trúc:

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 một phần:

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

}

Hoàn toàn mở rộng:

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

}

Để chạy, đầu tiên biên dịch mục thứ hai với: javac LookAndSayExpandedGolfed.java

Sau đó chạy với: java LookAndSayExpandedGolfed

Chỉnh sửa: Đã sửa lỗi.


Không làm việc cho tôi,Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4 at java.lang.String.charAt(String.java:658)
Octavia Togami

@KenzieTogami Đã sửa.
TheNumberOne

Tôi không nghĩ vậy, --1đáng lẽ phải --ithế?
Octavia Togami

@KenzieTogamie Vâng, đúng vậy. Bây giờ nó đã được sửa.
TheNumberOne

Thật tuyệt, thật tuyệt. Việc đảo ngược thất bại, tuy nhiên. 513211-> 11111.
Octavia Togami

1

Javascript (trong trình duyệt, 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)

Có thể rút ngắn 4 ký tự nếu bạn bỏ qua var hoặc thêm một vài ký tự với các phần tử không trung gian khác, nhưng hãy giả vờ rằng chúng tôi không phải là lập trình viên tồi trong một phút.

Chuyển sang chức năng cú pháp ngắn ES6 với giá trị đối số và trả về thay vì sử dụng dấu nhắc, cảnh báo cho IO có thể tiết kiệm nhiều hơn.

JSFiddle tại đây: http://jsfiddle.net/86L1w6Lk/


5
Đừng lo lắng về những điều đó var... tất cả chúng ta đều là "lập trình viên tồi" ở đây. ;)
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)]]))

1

Rắn hổ mang - 217

(186 nếu tôi có thể giả sử một usetuyên bố System.Text.RegularExpressionstồn tại ở nơi khác)

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

Sử dụng biểu thức chính quy thay thế bằng chức năng. Hàm regrec khác nhau và chức năng khác nhau tùy thuộc vào độ dài đầu vào là chẵn hoặc lẻ.

F=s=>s.replace((i=s.length&1)?/(.)(\1*)/g:/../g,x=>i?x.length+x[0]:x[1].repeat(x[0]))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.