Langtons Ameisen-ASCII-Kunst.


22

Zeichnen Sie den Weg von Langtons Ameise .

Beschreibung

Quadrate in einer Ebene sind unterschiedlich schwarz oder weiß gefärbt. Wir identifizieren willkürlich ein Quadrat als "Ameise". Die Ameise kann sich bei jedem Schritt in eine der vier Hauptrichtungen bewegen. Die Ameise bewegt sich nach folgenden Regeln:

  • Drehe an einem weißen Quadrat um 90 ° nach rechts, drehe die Farbe des Quadrats um und gehe eine Einheit vorwärts
  • Drehe dich an einem schwarzen Quadrat um 90 ° nach links, drehe die Farbe des Quadrats um und gehe eine Einheit vorwärts

Spezifikationen

  • Eingabe: eine ganze Zahl N zwischen 0 und 725 (einschließlich).
  • Ausgabe: Ein Raster von 17 x 17, das den "Pfad" der Ameise ab Schritt N darstellt.

Regeln

  • Die Ameise beginnt nach rechts zu schauen (3 Uhr).
  • Die Ameise beginnt in der Mitte des Gitters.
  • Verwenden Sie _#@für weiße Quadrate, schwarze Quadrate und die Ameise.
  • Das Gitter ist anfangs komplett weiß.
  • Sie können entweder ein komplettes Programm oder eine Funktion in einer interpretierten Sprache erstellen.
  • Eingabe per stdin oder Argument.

Beispiele

Update: Fall N = 450 Ausgabe war falsch.

N = 0

_________________
_________________
_________________
_________________
_________________
_________________
_________________
_________________
________@________
_________________
_________________
_________________
_________________
_________________
_________________
_________________
_________________

N = 1

_________________
_________________
_________________
_________________
_________________
_________________
_________________
_________________
________#________
________@________
_________________
_________________
_________________
_________________
_________________
_________________
_________________

N = 450

_________________
_________________
___________##____
____##______##___
___#__##___##_#__
__###_#@#__#__#__
__#_#_#_#__#_#___
_____###___#_____
_____#___________
_____#__###______
___#_#_#__#_#_#__
__#__#_#____###__
__#_##__##___#___
___##______##____
____##___________
_________________
_________________

@ Joey: ja "Vollständiges Programm oder Funktion. Eingabe durch Argument oder stdin.", Freistil :)
Eelvex

@Joey: Entschuldigung, wenn das nicht klar war: Du kannst entweder eine Funktion in einer interpretierten Sprache oder ein komplettes Programm ausführen. Sie können die Eingabe von stdin übernehmen oder als Argument angeben.
Eelvex

@Joey: Beachten Sie, dass die Ameise in Schritt 1 zuerst nach rechts dreht (jetzt nach Norden) und dann vorrückt. Sind Sie sicher, dass Sie das berücksichtigen?
Eelvex

@Joey: Ja, ich meinte im vorigen Kommentar " Süden" und du hast recht, das letzte Beispiel war für verschiedene N: - / (den Beispielabschnitt aktualisiert).
Eelvex

Antworten:


10

GolfScript - 67 Zeichen

~17.'_'*n+*\153:|;{|/()[124^.2/6+:6.1&17*)\2&(*|+:|;]@++}*|/();'@'@

Die Python-Lösung von hallvabo ähnelt dieser am meisten, daher beschreibe ich nur die Hauptunterschiede.

Die Karte wird als Zeichenfolge anstelle eines Arrays gespeichert. Auf diese Weise können wir einen Wert auf der Platine mit weniger Zeichen aktualisieren (da die Zeichenfolgen immer flach sind), sodass es einfach ist, ihn auf das gewünschte Ausgabeformat zu bringen.

Die Ameisenposition wird durch die Formel ((d&1)*17+1)*((d&2)-1)(dh .1&17*)\2&(*) inkrementiert , wobei d die Richtung ist. Wir verwenden die Variable 6, um die Initialisierung zu überspringen.


1
Oh, jetzt fühle ich mich wie ein GolfScript-Neuling.
aaaaaaaaaaa 19.03.11

:6- so Hipster. Ich würde es hassen, Ihren Code zu debuggen :-)
John Dvorak

9

Ruby 1.9, 104 Zeichen

f=->z{l=[*[r=1]*17,2]*17;c=152;z.times{c+=r=(r*r>1?r/18:-r*18)*l[c]*=-1};l[c]=0;l.map{|a|putc"@_
#"[a]}}

Eingabe über Funktionsargument.

  • (146 -> 142) Inline m
  • (142 -> 140) Suchen Sie nach r*r>1anstelle vonr.abs>1
  • (142 -> 128) Verwenden Sie String#scandiese Option , um die Ausgabe zu generieren. Geändert von a ==zu>
  • (128 -> 125) Veraltete Variable entfernt
  • (125 -> 122) Durch String#treine Bedingung ersetzen
  • (122 -> 122) Erzeugt nun die gleiche Ausgabe wie die aktualisierten Beispiele
  • (122 -> 111) Verwenden Sie beim Generieren des Pfads der Ameise Ints anstelle von Zeichen.
  • (111 -> 109) Ordnen Sie einige Ausdrücke neu an, um Klammern zu speichern
  • (109 -> 108) Code ist jetzt eine Funktion
  • (108 -> 104) Jedes Zeichen einzeln drucken

Funktionen sind erlaubt.
Eelvex

@Eelvex: Muss die Funktion einen String zurückgeben oder muss sie ihn ausgeben?
Ventero

Ausgabe.
Eelvex

6

Python, 123

n = input ()
d = x = 152
g = (17 * [95] + [10]) * 17
während n: d + = g [x] / 2; g [x] ^ = 124; x + = (1, -18, -1, 18) [d% 4]; n- = 1
g [x] = 64
drucke "% c" * 306% Tupel (g)

Nur eine kleine Überarbeitung meiner Python-Lösung von http://golf.shinh.org/p.rb?Langtons+Ant .


5

GolfScript 96 94 89

Meine Lieblings-Hasssprache ist zurück mit einem weiteren Haufen halblesbarer Sorta-Byte-Codes.

89 Version habe ich es endlich geschafft, @ in die Ausgabeschleife zu integrieren.

~289[0:c]*145:b;{.b>\b<)!..c++(4%:c[1 17-1-17]=b+:b;@++}@*{{(b(:b!.++'_#@@'1/=\}17*n\}17*

94 version:

~306[0:c]*152:b;{.b<\b>(!..c++(4%:c[1 18-1-18]=b+:b;\++}@*{{('_#'1/=\}17*(;n\}17*].b<\b>(;'@'\

Kommentiert:

               #Initialization.
~                  #Parse input.
306[0:c]*          #Make array of 306 0s, set c to 0 in the middle of that operation.
152:b;             #Set b to 152, remove 152 from the stack.
                   #b is a value for the ant's position, c for its rotation.

               #Run the algorithm.
{                  #Start of block.
    .b<\b>(        #Split the array at index b into before, after and value at b.
    !..            #Not the value and make 2 copies of it.
    c++            #Add the 2 copies to c.
    (4%:c          #Subtract 1, modulus by 4 and save the result to c.
    [1 18-1-18]=   #Define an array and take element number c.
    b+:b;          #Add b to the value, save result to b, remove result from stack.
    \++            #Reform the array.
}@*                #Switch the input to the top of the stack and run the block input times.

               #Convert array of 1s and 0s to the correct characters.
{                  #Start of block.
    {              #Start of block.
        ('_#'1/=   #Take the first array element, convert it to either '_' or '#'.
        \          #Switch the array to the top of the stack.
    }17*           #Execute block 17 times.
    (;n\           #Discard the 18th element of the line, write a lineshift.
}17*               #Execute block 17 times.

               #Insert the @.
]                  #Put everything in an array.
.b<\b>(            #Split the array at index b into before, after and value at b.
;'@'\              #Ditch the value at b, write a @ and shift it into place.

Bearbeiten, ich könnte auch eine große Version machen, hier sind 59 * 59 und 10500 Iterationen:

~59:a.*[0:c]*1741:b;{.b>\b<)!..c++(4%:c[1 a-1-59]=b+:b;@++}@*{{(b(:b!.++'_#@@'1/=\}a*n\}a*

.

___________________________________________________________
___________________________________________________________
_________________________##__##____________________________
________________________#__@_###___________________________
_______________________###__#_#_#__________________________
_______________________#####_#__##_________________________
________________________#___##_##_#________________________
_________________________###___#__##_______________________
__________________________#___##_##_#______________________
___________________________###___#__##_____________________
____________________________#___##_##_#__##________________
_____________________________###___#__##__##_______________
______________________________#___##_##__##___#____________
________________________####___###___#___#__###____________
_______________________#____#___#___##_####___#____________
______________________###____#___#_#______#_##_#___________
______________________###____#_##_____#_##__#_##___________
_______________________#____#___##_#_#_____##______________
_______________________#_#______#_#####__#___#_____________
______________________#___#####__________##_######_________
______________________###__##__#_##_#_#_#___##_#_##________
____________________##__#_#######_#___#__###____##_#_______
___________________#__#__######_##___#__#_##___#___#_______
__________________#____#_#_##_#__######_#######___#________
__________________#_####_##_#_####____##__##_#_##_#________
___________________#____####___#__#_######_##____###_______
______________________#___#_##_#_###_#__##__##___###_______
_________________________#######____#__##_##_#_____#_______
_________________####__##_##__####_##_##_##__#_____#_______
________________#____#_#___###_##_###____#_####____#_______
_______________###_______###_#_#_#####____#_#______#_______
_______________#_#___###_####_##_#___##_###_##_____#_______
_____________________##_##__####____####_#_#_#_____#_______
________________#____#__##___###__###_____###______#_______
________________##___##_###_####__#______###___##__#_______
________________##_#_####_____#___#__#_##_###_##___#_______
_______________####_##___##_####__#_#__#__#__###___#_______
_______________#_##_###__#_#_##_#_#_____#_#_____#_#________
___________________#_#__#____##_##__#_#__###_##____________
___________________##_#____#__#####_#____#____#__#_#_______
__________________#_##_#__#____##_##_#__###______###_______
________________#_#___#__#__#__#__###___##__##____#________
_______________###_#_#####_######_###_#######_#_##_________
_______________#_#_#____#####___##__#####_#####____________
_________________#__##___#______#__#_##__###_###___________
______________####___#####_#########___#_#_________________
_________##____#__#_____###_#_#___#_###__###_______________
________#__#__####_##___###_##___###_##_____##_____________
_______###____#_##_#_#####___#____#__#__##_###_____________
_______#_#####_#_#___##__##_____#____#___#__#______________
___________######_####__##_#___#__##__#_#_##_______________
_________##______#_###_##__####___#___###__________________
__________#__#_#####__#___#_##___#__#__#___________________
__________##_###_#######_____#_____#_##____________________
_________#_#__##_##______#___##____#_______________________
________#__#_####________###__##__#________________________
________#_##_###____________##__##_________________________
_________##________________________________________________
__________##_______________________________________________

5

Windows PowerShell, 119 118

for($p,$n,$g=144,+"$args"+,1*289;$n--){$d+=$g[$p]*=-1
$p+='B0@R'[$d%4]-65}$g[$p]=0
-join'@_#'[$g]-replace'.{17}',"$&
"

4

PHP, 350 309 307 312 174 161 166 159 151 149 147 144 143

<?$p=144;while($i=$argv[1]--){$g[$p]=$a=2-$g[$p];$d+=--$a;$p+=(1-($d&2))*(1+16*($d&1));}while($i++<288)echo$i%17?$i!=$p?$g[$i]?"#": _:"@":"\n";

Ungolfed

$p = 144; // Set initial pointer

while($i = $argv[1]--){ // Ends at -1
    $g[$p] = $a = 2 - $g[$p]; // Either returns true (2) or false(0)

    $d += --$a; // Adds 1 (2-1) or removes 1 (0-1) from the direction

    $p += (1 - ($d & 2)) * (1 + 16 * ($d & 1));
}

while($i++ < 288)
    echo $i % 17? $i != $p? $g[$i]? "#" : @_ : "@" : "\n"; // Prints the correct character

350 -> 309: Verschiedene Komprimierungstechniken mit den for () - Schleifen, die ebenfalls aktualisiert wurden, um die korrekte Ausgabe anzuzeigen.
309 -> 307: Konvertierte main for () -Schleife in eine while () -Schleife.
307 -> 312: Vergessen, es zu ändern, um argv zu verwenden.
312 -> 174: Auf der Grundlage einer anderen Antwort neu codiert.
174 -> 161: Standardmäßig wird nicht mehr das gesamte Array verwendet.
161 -> 166: Argv gewinnt erneut.
166 -> 159: Keine Notwendigkeit, argv neu zu definieren [1].
159 -> 151: Keine Voreinstellung mehr, PHP macht das automatisch.
151 -> 149: Ein Satz von Klammern wurde entfernt, die Reihenfolge der Operationen beseitigt die Notwendigkeit.
149 -> 147: Die letzte for () -Schleife wurde gekürzt, Klammern werden nicht benötigt.
147 -> 144:Last for () Schleife ist jetzt eine while () Schleife.
144 -> 143: Verwendet eine temporäre Variable zum Speichern eines Zeichens.


Ich sehe, dass du meine Raster- und Richtungstricks angewendet hast und 138 Zeichen aus deinem Code entfernt hast, schön!
PatrickvL

4

C 166, 162

Hier eine Übersetzung meines Delphi-Ansatzes nach C, die zeigt, wie kompakt C sein kann. Ich habe mir den bedingten Newline-Trick von fR0DDY ausgeliehen (danke Kumpel!):

g[289]={0},a=144,d,i,N;main(){scanf("%d",&N);while(N--)g[a]=2-g[a],d+=g[a]-1,a+=(1-(d&2))*(1+d%2*16);for(g[a]=1;i<289;)printf("%s%c",i++%17?"":"\n","_@#"[g[i]]);}

Die eingerückte, kommentierte Version sieht folgendermaßen aus:

g[289]={0}, // g: The grid is initially completely white. (size=17*17=289)
a=144, // a: Ant position starts at the center of the grid (=8*17+8=144)
d, // Assume 0=d: Ant start 'd'irection faces right (=0, see below)
i,
N;
main(){
  scanf("%d",&N);
  while(N--)
    // Flip the color of the square:
    g[a]=2-g[a],
    // Turn 90° right if at an '_' space, 90° left otherwise :
    d+=g[a]-1,
    // Move one unit forward;
    //   For this, determine the step size, using the two least significant bits of d.
    //   This gives the following relation :
    //     00 = 0 =  90° = right =   1
    //     01 = 1 = 180° = down  =  17
    //     10 = 2 = 270° = left  = - 1
    //     11 = 3 =   0° = up    = -17
    //   (d and 2) gives 0 or 2, translate that to 1 or -1
    //   (d and 1) gives 0 or 1, translate that to 1 or 17
    //   Multiply the two to get an offset 1, 17, -1 or -17 :
    a+=(1-(d&2))*(1+d%2*16);
  // Place the ant and print the grid :
  for(g[a]=1;i<289;)
    printf("%s%c",i++%17?"":"\n","_@#"[g[i]]); // 0 > '_', 1='@', 2 > '#'
}

+1. Ich mag die Tricks "_@#"[g[i]]unda+=(1-(d&2))*(1+(16*(d&1)))
FR0DDY

(1+d%2*16)spart ein paar Zeichen.
Nabb

@Nabb: Das spart in der Tat 4 Zeichen, danke für den Vorschlag!
PatrickvL

4

Delphi, 217

var g,a:PByte;i,d,Word;begin g:=AllocMem(306);a:=g+153;Read(i);for n:=1to i do begin a^:=2-a^;d:=d-1+a^;a:=a+(1-2and d)*(1+17*(1and d))end;a^:=1;for n:=1to 306do if n mod 18=0then WriteLn else Write('_@#'[1+g[n]])end.

Der eingerückte und kommentierte Code lautet wie folgt:

var
  g,a:PByte;
  i,d,n:Int32;
begin
  g:=AllocMem(306); // g: The grid is initially completely white. (size=18*17=306)
  // Assume 0=d: Ant start 'd'irection faces right (=0, see below)
  a:=g+153; // a: Ant position starts at the center of the grid (=8*18+9=153)
  Read(i);
  for n:=1to i do
  begin
    // Flip the color of the square;
    a^:=2-a^;
    // Turn 90° right if at an '_' space, 90° left otherwise;
    d:=d-1+a^;
    // Move one unit forward;
    //   For this, determine the step size, using the two least significant bits of d.
    //   This gives the following relation :
    //     00 = 0 =  90° = right =   1
    //     01 = 1 = 180° = down  =  18
    //     10 = 2 = 270° = left  = - 1
    //     11 = 3 =   0° = up    = -18
    //   (d and 2) gives 0 or 2, translate that to 1 or -1
    //   (d and 1) gives 0 or 1, translate that to 1 or 18
    //   Multiply the two to get an offset 1, 18, -1 or -18 :
    a:=a+(1-2and d)*(1+17*(1and d))
  end;
  // Place the ant and print the grid :
  a^:=1; // 0 > '_', 1='@', 2 > '#'
  for i:=1to 306do
    if i mod 18=0then // we insert & abuse column 0 for newlines only (saves a begin+end pair)
      WriteLn
    else
      Write('_@#'[1+g[i]])
end.

Eingang:

450

Ausgabe :

_________________
_________________
___________##____
____##______##___
___#__##___##_#__
__###_#@#__#__#__
__#_#_#_#__#_#___
_____###___#_____
_____#___________
_____#__###______
___#_#_#__#_#_#__
__#__#_#____###__
__#_##__##___#___
___##______##____
____##___________
_________________
_________________

@Patrick: Das Beispiel war falsch, bitte überprüfen Sie die Updates. (und es scheint, dass Sie Schritt 451 ausgeben :)).
Eelvex

@Eelvex: Danke. Ich habe den Fall 'N = 0' zu einem Preis von 4 Zeichen behoben ... jetzt muss ich sie wieder zurückgewinnen! ;-)
PatrickvL

@Eelvex: PS: Nein +1 für das Erkennen Ihres Fehlers vor 3 Stunden mit nur einer bescheidenen Bemerkung, es könnte meine Schuld sein? ;)
PatrickvL

@ Patrick: Ich habe auf <200 gewartet, aber ok ... :)
Eelvex

@Eelvex: LOL, dort ankommen ... (bis zu 238 bereits)
PatrickvL

3

C 195 Zeichen

x=144,T,p=1,i,N[289]={0},a[]={-17,1,17,-1};c(t){p=(p+t+4)%4;x+=a[p];}main(){scanf("%d",&T);while(T--)N[x]=(N[x]+1)%2,c(N[x]?1:-1);for(;i<289;i++)printf("%s%c",i%17?"":"\n",i-x?N[i]?'#':'_':'@');}

http://www.ideone.com/Dw3xW

Ich bekomme das für 725.

_________________
_________________
___________##____
____##______##___
___#___##__##_#__
__###____#_#__#__
__#_#_#__#_#_#___
______###____#__@
_______###__#__#_
_____#_#____#___#
___#_#_#_##____#_
__#__#_#_#_#_###_
__#_##_#_____####
___##_#____#_####
____###___####_#_
_______#__#__##__
________####_____

Mit p+=t+4;x+=a[p%4];statt p=(p+t+4)%4;x+=a[p];drei Zeichen speichern.
Joey

3

sed, 481 Zeichen

#n
1{s/.*/_________________/;h;H;H;H;G;G;G;G;s/^\(.\{152\}\)_/\1@/;s/$/;r/;ta;};x;:a;/;r/br;/;d/bd;/;l/bl;/;u/bu;:w;y/rdlu/dlur/;bz;:b;y/rdlu/urdl/;bz;:r;s/@\(.\{17\}\)_/#\1@/;tw;s/@\(.\{17\}\)#/#\1!/;tw;s/_\(.\{17\}\)!/@\1_/;tb;s/#\(.\{17\}\)!/!\1_/;tb;:d;s/_@/@#/;tw;s/#@/!#/;tw;s/!_/_@/;tb;s/!#/_!/;tb;:l;s/_\(.\{17\}\)@/@\1#/;tw;s/#\(.\{17\}\)@/!\1#/;tw;s/!\(.\{17\}\)_/_\1@/;tb;s/!\(.\{17\}\)#/_\1!/;tb;:u;s/@_/#@/;tw;s/@#/#!/;tw;s/_!/@_/;tb;s/#!/!_/;tb;:z;h;${s/!/@/;s/;.//p}

Kann auf 478 Zeichen reduziert werden, indem die erste Zeile entfernt und mit ausgeführt wird -n

Benötigt N Zeilen für die Eingabe, z. wenn ausgeführt als

seq 450 | sed -f ant.sed

Ausgänge:

_________________
_________________
___________##____
____##______##___
___#__##___##_#__
__###_#@#__#__#__
__#_#_#_#__#_#___
_____###___#_____
_____#___________
_____#__###______
___#_#_#__#_#_#__
__#__#_#____###__
__#_##__##___#___
___##______##____
____##___________
_________________
_________________

3

Perl, 110 Zeichen

$p=144;$p+=(1,-17,-1,17)[($d+=($f[$p]^=2)+1)%4]for 1..<>;$f[$p]=1;print$_%17?'':$/,qw(_ @ #)[$f[$_]]for 0..288

Die Nummer wird aus der ersten Zeile von STDIN gelesen. Der Rest der Eingabe wird ignoriert.

Etwas besser lesbar:

$p=144;
$p += (1,-17,-1,17)[($d+=($f[$p]^=2)+1) % 4] for 1..<>;
$f[$p]=1;
print $_%17 ? '' : $/, qw(_ @ #)[$f[$_]] for 0..288

Bearbeitungen

  • (112 → 111) Keine Aktualisierung $dmit dem Modulo-4-Wert erforderlich .

  • (111 → 110) Kann jetzt das $dInkrement inline setzen

Anhang (109 Zeichen)

Wir können es ein Zeichen kürzer haben, wenn Sie froh sind, den Sonderfall des N=0Scheiterns zu haben (er gibt das @Zeichen für die Ameise nicht aus). Alle anderen Eingaben funktionieren korrekt:

$p+=(1,-17,-1,17)[($d+=($f{$p+0}^=2)+1)%4]for 1..<>;$f{$p}=1;print$_%17-9?'':$/,qw(_ @ #)[$f{$_}]for-144..144

Die Unterschiede sind, dass wir jetzt %fstatt verwenden, @fdamit wir negative Indizes verwenden können, und wir iterieren -144..144statt 0..288. Das erspart das Initialisieren $p.


1

Mathematica, 94 Zeichen

a@_=d=1;a@Nest[#+(d*=(a@#*=-1)I)&,9-9I,Input[]]=0;Grid@Array["@"[_,"#"][[a[#2-# I]]]&,17{1,1}]

1

> <> 122 Bytes

Auf die Gefahr einer kleinen Threadnekromantie dachte ich, eine Antwort in> <> zu schreiben, wäre eine interessante Herausforderung ...

1&f8r\
1-:?!\r:@@:@$:@@:@g:2*1+&+4%:&}1$-@p{:3$-5gaa*-$@+@5gaa*-+r
2}p70\~
a7+=?\:@@:@g4+5go$1+:
o053.>~1+:64*=?;a
dedc_#@

Dieses Programm erwartet, dass die Anzahl der zu berechnenden Schritte vor der Ausführung auf dem Stapel vorhanden ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.