Look-and-Say: Conway überarbeitet

16

Sie sollten alle bereits mit der Conway-Sequenz (auch bekannt als "Look-and-Say" -Sequenz) vertraut sein :

     1
    11
    21
  1211
111221
312211
etc

Sie können auch mit einer beliebigen Zahl als Startpunkt beginnen. Sei f(s)das nächste Element der Sequenz. Jetzt skönnen wir für jede gegebene finden f(s). Das Gegenteil ist nicht so trivial: Es ist nicht für jeden ymöglich, den Vorgänger sso zu finden, dass f(s) = y. ZB weil y = 1wir keinen Vorgänger finden können. Aber wenn yeine hat sogar Länge können Sie ihn in Ziffernpaare unterteilen , die jeweils einen Teil eines Vorgänger beschreiben:

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

Auf diese Weise können wir für jede gerade Länge einen eindeutigen Vorgänger definieren y.

Hinweis : Der so sdefinierte 'Vorgänger' erfüllt im Allgemeinen NICHT f(s) = y.

Tor

Schreiben Sie ein Funktions- / Programm-Snippet, das eine Ziffernfolge als Eingabe akzeptiert

  • berechnet das nächste Element der Conway-Sequenz, wenn die Länge der Eingabezeichenfolge ungerade ist
  • berechnet den Vorgänger der Eingabezeichenfolge wie oben definiert, wenn die Länge der Eingabezeichenfolge gerade ist .

Kürzester Code in Bytes gewinnt.

Aktuelle Fragen zu den Look-and-Say-Sequenzen:

fehlerhaft
quelle
1
Ich bin verwirrt. Können Sie erklären , wie 513111teilt sich in 51, 32und 11?
Squeamish Ossifrage
1
Ich denke, dies ist ein kombiniertes Duplikat einer Look-and-Say-Sequenz-Challenge und einer Run-Length-Decodierungs-Challenge (ich bin sicher, wir hatten diese).
Martin Ender
3
Was wäre der Vorgänger von 11111111111111? Nach Ihrer Spezifikation wäre es 1111111. Sie sollten Ihre Spezifikation ändern, um eine angemessene Antwort darauf zu definieren.
TheNumberOne
1
@TheBestOne hat 11111111111111einfach keinen Vorgänger. Es ist eine illegale Eingabe.
kay
2
@TheBestOne Ja, das ist richtig, ich habe eine beliebige Regel für den Vorgänger definiert, die nicht immer mit einem "echten" Vorgänger übereinstimmt.
Fehler

Antworten:

3

CJam, 46 45 44 43 42 Bytes

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

Teste es hier. Es nimmt die Nummer auf STDIN und gibt das Ergebnis an STDOUT aus.

Martin Ender
quelle
si-> ~= 45
Optimierer
@Optimizer Danke, ich habe vergessen, dass du einen Charakter auswerten kannst.
Martin Ender
5

Rubin, 125 120 119 101 Bytes

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

Zeichenketteneingabe über Funktion f:

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

Mit Notizen erweitert:

# 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
}
August
quelle
4

Prolog - 170 Bytes

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

Dieser Ausschnitt definiert die Funktion (-)/2. Sie können es wie aufrufen

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

In dieser Sequenz scheint es nur eine Länge mit einer ungeraden Parität zu geben: die Initiale [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.

Lesbar:

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
quelle
3

Python: 139 Zeichen

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

einzelner Testfall

print f('1111122221111222112')
>>> 514241322112
print f('514241322112')
>>> 1111122221111222112
Averykhoo
quelle
Sie können das Leerzeichen von s)] ifbis entfernen s)]if.
Bakuriu
Sie können auch das Leerzeichen zwischen2 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
_#_=[]

Wenn es von stdin / stdout sein muss, addieren Sie main=interact lfür 150 144 131 Zeichen. Die Funktion wird aufgerufen 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
quelle
Könnten Sie bitte ein Anwendungsbeispiel nennen? Während ich l "11"zur Arbeit ging, bekam ich eine Ausnahme mit l "111"oderl "1111111111111"
Paul Guyot
@PaulGuyot, Scheint so, als hätte das ein paar Zeichen meiner Punktzahl gekürzt. Danke :-)
Zaq
3

Perl - 98 Bytes

Die Größe all dieser Steueranweisungen stört mich, aber ich bin ziemlich glücklich darüber, wie die Regexes ausgearbeitet haben.

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

Unkomprimiert:

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

Die Hauptfunktion ist f, wobei die Eingabe als Erlang-Zeichenfolge und die Ausgabe als Zeichenfolge zurückgegeben wird.

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

Die Funktion kann um 15 Byte gekürzt werden (190), indem die Groß- und Kleinschreibung für mehr als 9 identische Zeichen weggelassen wird. fruft auf, gwas den Vorgänger rekursiv berechnet, und wenn die Anzahl der Zeichen ungerade ist (gefunden am Ende der Berechnung), ruft es eine Funktion auf, idie zusammen mit hdem nächsten Element berechnet.

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

Ich finde es schön, dass es keine Hilfsfunktionen gibt :-).

stolzer haskeller
quelle
|x:y:z<-r- Ich wusste gar nicht, dass du das kannst. Das ist so cool!
Flonk
@Flonk Es heißt "Pattern Guards". Früher war es eine Erweiterung und in einer der Versionen von Haskell wurde sie hinzugefügt :-)
stolzer Haskeller
Das macht vieles so viel einfacher. Sie lernen jeden Tag etwas Neues! :)
Flonk
2

APL (45)

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

Ja, das ist eine gültige Funktionsdefinition, auch von außen.

      ∊{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
quelle
2

Java 7, Score = 252 235 Bytes

Ja, es ist wieder Java. die schlechteste Golfsprache der Welt. Dieser Ansatz verwendet Zeichenfolgen. Beliebig große Ganzzahlen werden in Java unterstützt, benötigen jedoch viel mehr Platz für die Codeeingabe.

Mit anrufen f(intputString). Gibt den entsprechenden String zurück.

Golf gespielt:

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 Erweitert mit Strukturcode:

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

}

Teilweise Golf gespielt:

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

}

Komplett erweitert:

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

}

Zum Ausführen kompilieren Sie zuerst den zweiten Eintrag mit: javac LookAndSayExpandedGolfed.java

Dann lauf mit: java LookAndSayExpandedGolfed

Bearbeiten: Fehler behoben.

Die Nummer eins
quelle
Funktioniert nicht für mich,Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4 at java.lang.String.charAt(String.java:658)
Octavia Togami
@ KenzieTogami Behoben.
TheNumberOne
Ich glaube nicht, --1soll das sein --i?
Octavia Togami
@ KenzieTogamie Ja, das ist es. Es ist jetzt behoben.
TheNumberOne
Cool, das geht. Der Umkehrer fällt jedoch aus. 513211-> 11111.
Octavia Togami
1

Javascript (im 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)

Kann um 4 Zeichen gekürzt werden, wenn Sie var überspringen, oder um ein paar Zeichen mehr, wenn Sie andere nicht-geordnete Zwischenglobale verwenden, aber tun wir mal so, als wären wir für eine Minute keine schlechten Programmierer.

Wenn Sie zur ES6-Kurzsyntaxfunktion mit Argument und Rückgabewert wechseln, anstatt die Eingabeaufforderung zu verwenden, können Sie mit der E / A-Warnung weitere Einsparungen erzielen.

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

user33068
quelle
5
Mach dir keine Sorgen um diese var... wir sind alle "schlechte Programmierer" hier. ;)
Martin Ender
1

Python 3 - 159 Bytes

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)]]))
Beta-Zerfall
quelle
1

Cobra - 217

(186 wenn ich davon ausgehen kann, dass eine useAussage für System.Text.RegularExpressionswoanders existiert)

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(''))
Οurous
quelle
1

JavaScript (ES6) 85

Mit regulären Ausdrücken durch Funktion ersetzen. Unterschiedliche Ausdrücke und unterschiedliche Funktionen, abhängig davon, ob die Länge der Eingabe gerade oder ungerade ist.

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