Przyjrzyj się: Conway ponownie

16

Wszyscy powinniście już znać sekwencję Conwaya (czyli sekwencję „look-and-say”) :

     1
    11
    21
  1211
111221
312211
etc

Możesz także zacząć od dowolnej liczby jako punktu początkowego. Niech f(s)będzie kolejnym elementem sekwencji. Teraz dla każdego, co smożemy znaleźć f(s). Odwrotna sytuacja nie jest tak trywialna: nie jest ymożliwe znalezienie stakiego poprzednika f(s) = y. Np. y = 1Nie możemy znaleźć poprzednika. Ale jeśli yma parzystą długość, możesz podzielić ją na pary cyfr, które opisują każdą część poprzednika:

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

W ten sposób możemy zdefiniować unikalnego poprzednika dla każdej yrównej długości.

Uwaga : Tak szdefiniowany „poprzednik” zasadniczo NIE spełnia wymagań f(s) = y.

Cel

Napisz fragment funkcji / programu, który przyjmuje ciąg cyfr jako dane wejściowe

  • oblicza następny element sekwencji Conwaya, jeśli długość ciągu wejściowego wynosi nieparzysta
  • oblicza poprzednika ciągu wejściowego, jak zdefiniowano powyżej, jeśli długość ciągu wejściowego jest równa .

Najkrótszy kod w bajtach wygrywa.

Ostatnie pytania oparte na sekwencjach typu look-and-say:

wada
źródło
1
Jestem zmieszany. Można wyjaśnić, jak 513111dzieli 51, 32i 11?
piskliwy ossifrage
1
Wydaje mi się, że jest to połączony duplikat jakiegoś wyzwania polegającego na wyglądzie i powiedzeniu sekwencji oraz wyzwaniu dekodowania podczas całej serii (jestem pewien, że je mieliśmy).
Martin Ender
3
Jaki byłby jego poprzednik 11111111111111? Zgodnie z twoją specyfikacją byłoby 1111111. Powinieneś zmodyfikować specyfikację, aby zdefiniować rozsądną odpowiedź na to pytanie.
TheNumberOne
1
@TheBestOne 11111111111111po prostu nie ma poprzednika. To nielegalny wkład.
kay jest rozczarowany
2
@TheBestOne Tak, to prawda, zdefiniowałem arbitralną regułę dla poprzednika, która nie zawsze pasuje do „prawdziwego” poprzednika.
flawr

Odpowiedzi:

3

CJam, 46 45 44 43 42 bajtów

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

Sprawdź to tutaj. Pobiera numer na STDIN i wypisuje wynik na STDOUT.

Martin Ender
źródło
si-> ~= 45
Optymalizator
@Optimizer Dzięki, zapomniałem, że możesz ewaluować postać.
Martin Ender
5

Rubin, 125 120 119 101 bajtów

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

Ciąg wejściowy pobrany za pomocą funkcji f:

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

Rozszerzony o notatki:

# 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
}
sierpień
źródło
4

Prolog - 170 bajtów

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

Ten wycinek określa funkcję (-)/2. Możesz to wywołać jak

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

Wydaje się, że w tej sekwencji występuje tylko jedna długość z nieparzystą parzystością: początkowa [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.

Czytelny:

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 jest rozczarowany w SE
źródło
3

Python: 139 znaków

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

pojedynczy przypadek testowy

print f('1111122221111222112')
>>> 514241322112
print f('514241322112')
>>> 1111122221111222112
averykhoo
źródło
Możesz usunąć spację od s)] ifdo s)]if.
Bakuriu
Możesz także usunąć odstęp pomiędzy2 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
_#_=[]

Jeśli musi to być od standardowego / standardowego, dodaj main=interact ldo 150 144 131 wszystkich znaków. Funkcja jest wywoływana 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
źródło
Czy możesz podać przykład użycia? Podczas l "11"pracy dostaję wyjątek z l "111"lubl "1111111111111"
Paul Guyot
@PaulGuyot, Wygląda na to, że naprawienie obniżyło o kilka znaków mój wynik. Dzięki :-)
Zaq
3

Perl - 98 bajtów

Rozmiar wszystkich tych instrukcji sterujących mnie wkurza, ale jestem całkiem zadowolony z tego, jak działały wyrażenia regularne.

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

Nieskompresowane:

($_)=@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
źródło
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.

Główną funkcją jest f, przyjmowanie danych wejściowych jako ciągu Erlanga i zwracanie danych wyjściowych również jako ciągu.

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

Funkcja może zostać zmniejszona o 15 bajtów (190), porzucając wymóg dotyczący więcej niż 9 znaków identycznych. fwywołuje grekurencyjne obliczenia poprzednika, a jeśli liczba znaków jest nieparzysta (stwierdzona w momencie zakończenia obliczeń), wywołuje funkcję, iktóra w połączeniu z hoblicza następny element.

Paul Guyot
źródło
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

Myślę, że to miłe, że nie używa żadnych funkcji pomocniczych :-).

dumny haskeller
źródło
|x:y:z<-r- Nie wiedziałem, że możesz to zrobić. To jest takie fajne!
Flonk
@Flonk Nazywa się to „strażnikami wzorców”. Kiedyś było rozszerzeniem i do jednej z wersji Haskella dodano :-)
dumny haskeller
To sprawia, że ​​wiele rzeczy jest o wiele łatwiejszych. Każdego dnia uczysz się czegoś nowego! :)
Flonk
2

APL (45)

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

Tak, to poprawna definicja funkcji, nawet z zewnętrzną stroną.

      ∊{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
źródło
2

Java 7, wynik = 252 235 bajtów

Tak, to znowu java; najgorszy język golfa na świecie. To podejście wykorzystuje ciągi znaków. Arbitralnie duże liczby całkowite są obsługiwane w Javie, ale zajęłyby znacznie więcej miejsca na kodowanie.

Zadzwoń z f(intputString). Zwraca odpowiedni ciąg.

Gra w golfa:

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

Golfowy Rozszerzony z kodem struktury:

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

}

Częściowo gra w golfa:

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

}

Całkowicie rozbudowany:

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

}

Aby uruchomić, najpierw skompiluj drugi wpis za pomocą: javac LookAndSayExpandedGolfed.java

Następnie uruchom z: java LookAndSayExpandedGolfed

Edycja: Naprawiono błąd.

Numer jeden
źródło
Nie działa dla mnieException in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4 at java.lang.String.charAt(String.java:658)
Octavia Togami,
@KenzieTogami Naprawiono.
TheNumberOne
Nie sądzę, tak --1powinno być --i?
Octavia Togami
@KenzieTogamie Tak, jest. Teraz jest naprawione.
TheNumberOne
Fajnie, to działa. Odwrócenie kończy się jednak niepowodzeniem. 513211-> 11111.
Octavia Togami,
1

JavaScript (w przeglądarce, 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)

Może zostać skrócony o 4 znaki, jeśli pominiesz var, lub kilka innych znaków z innymi pośrednimi niepodzielonymi globalsami, ale udawajmy, że nie jesteśmy złymi programistami przez minutę.

Przejście na funkcję krótkiej składni ES6 z argumentem i wartością zwracaną zamiast monitu, alert dla IO może zaoszczędzić więcej.

JSFiddle tutaj: http://jsfiddle.net/86L1w6Lk/

użytkownik33068
źródło
5
Nie martw się o te var... wszyscy jesteśmy tutaj „złymi programistami”. ;)
Martin Ender
1

Python 3 - 159 bajtów

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)]]))
Rozpad beta
źródło
1

Kobra - 217

(186, jeśli mogę założyć, że useoświadczenie System.Text.RegularExpressionsistnieje w innym miejscu)

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(''))
Obrzydliwe
źródło
1

JavaScript (ES6) 85

Używając wyrażenia regularnego zamień na function. Różne wyrażenia regularne i różne funkcje w zależności od długości wejściowej są parzyste lub nieparzyste.

F=s=>s.replace((i=s.length&1)?/(.)(\1*)/g:/../g,x=>i?x.length+x[0]:x[1].repeat(x[0]))
edc65
źródło