Nummern tauschen [geschlossen]

10

Dies ist ein häufiges Rätsel, das viele von Ihnen manuell gelöst haben. Jetzt ist es an der Zeit, einen Algorithmus zu schreiben, um dasselbe zu lösen.

Es gibt gleich viele Matchsticks, die in zwei verschiedenen Seiten in einer Richtung zueinander angeordnet sind. Es gibt einen einzigen leeren Raum zwischen ihnen. Sagen Sie etwas wie die folgende Abbildung (wenn die Gesamtzahl der Matchsticks 4 beträgt).

Geben Sie hier die Bildbeschreibung ein

Jeder Stock kann entweder einen Schritt nach vorne schieben (wenn der unmittelbare vordere Raum frei ist) oder er kann über einen Stock in seiner Vorderseite gesprungen werden und in den freien Raum landen (wenn dieser Raum frei ist). Die Bewegung in umgekehrter Richtung ist nicht möglich (auch der Platz ist frei). Ein Rückwärtssprung ist ebenfalls nicht zulässig. In einem Schritt ist nur eine Bewegung zulässig.

Jetzt müssen Sie einen Algorithmus schreiben, um die erforderlichen Mindestschritte zu ermitteln, mit denen alle Match-Sticks auf der linken Seite auf der rechten Seite und alle Match-Sticks auf der rechten Seite auf der linken Seite landen.

Zum Beispiel: Wenn es insgesamt 2 Streichhölzer gibt (1 auf jeder Seite), sind die Schritte:

Geben Sie hier die Bildbeschreibung ein

Hinweis: In der obigen Abbildung wurde der linke Seitenstock zuerst bewegt. Eine andere Lösung besteht, wenn sich der rechte Seitenstab zuerst bewegt. Für dieses Problem müssen Sie jedoch nur eine Lösung angeben. Dies setzt auch voraus, dass sich der linke Stick zuerst bewegt.

Die folgende Abbildung beschreibt die Bewegungen mit 4 Streichhölzern (2 auf jeder Seite):

Geben Sie hier die Bildbeschreibung ein

Hinweis: In der obigen Abbildung wurde der linke Seitenstock zuerst bewegt. Eine andere Lösung besteht, wenn sich der rechte Seitenstab zuerst bewegt. Für dieses Problem müssen Sie jedoch nur eine Lösung angeben. Dies setzt auch voraus, dass sich der linke Stick zuerst bewegt.

[Annahme: Die Eingabe kann eine beliebige gerade Zahl zwischen 02 und 14 sein (dh 1 bis 7 Matchsticks auf jeder Seite). Für Eingaben außerhalb dieses Bereichs müssen Sie weder eine Validierung durchführen noch eine Fehlermeldung angeben. Hinweis: In der Ausgabe wird jeder Schritt durch ein '|' getrennt. (Rohr-) Charakter. COBOL-Programmierer sollten immer PIC 9 (2) als Eingabegröße annehmen und können auch davon ausgehen, dass die Ausgabe eine feste maximale Länge von 450 Zeichen hat und rechts mit Leerzeichen aufgefüllt ist.]


Beispieleingabe:

02  

Beispielausgabe:

01To02|03To01|02To03|


Beispieleingabe:

04  

Beispielausgabe:

02To03|04To02|05To04|03To05|01To03|02To01|04To02|03To04|


Beispieleingabe:

06  

Beispielausgabe:

03To04|05To03|06To05|04To06|02To04|01To02|03To01|05To03|07To05|06To07|04To06|02To04|03To02|05To03|04To05|
user2076421
quelle
Wenn Sie die Bilder nicht direkt einfügen können, können Sie dann Links bereitstellen, in denen andere Personen sie bearbeiten können?
Peter Taylor
2
Ich habe ein paar schnelle Bilder gemacht. Hoffentlich entsprechen sie der Absicht des ursprünglichen Autors.
Primo
3
Voraussetzung für den Sieg?
Shmiddty

Antworten:

3

APL 129

Der folgende Code übernimmt die Bildschirmeingabe und -ausgabe in dem angegebenen Format auf dem Bildschirm:

n←n,n++\1↓z←(⌽z),((¯1*~2|n)×n⍴2),z←⌽∊(¯1*2|⍳n)ר1,((⍳(n←.5×⍎⍞)-1)⍴¨2),¨1⋄(∊(((¯2↑¨'0',¨⍕¨n),¨⊂'To'),¨(¯2↑¨'0',¨⍕¨n-z)),¨⊂'|')~' '

Ein gutes Drittel des Codes wird für die Formatierung der Ausgabe benötigt. Die Logik wird durch das Auftreten des Symbols ⋄ im Code vervollständigt.

Unten ist das Ergebnis für eine Eingabe von 08 zur Überprüfung:

04To05|06To04|07To06|05To07|03To05|02To03|04To02|06To04|08To06|09To08|07To09|05To07|03To05|01To03|02To01|04To02|06To04|08To06|07To08|05To07|03To05|04To03|06To04|05To06|
Graham
quelle
1
Ich habe immer das Gefühl, dass APL betrügt>. <
Shmiddty
@Shmiddty Ich befürchte, dass jede rein symbolbasierte Sprache wie APL, J, GolfScript usw. höchstwahrscheinlich Code Golf gegen ausführlichere wortbasierte Sprachen gewinnen wird;)
Graham
3

Javascript 178 174 161

prompts für ndann alerts Antwort. (Keine 0Polsterung)

Neueste:

t=1+(m=prompt(s=i='')/2);for(z=Math.abs;i++<m*2;)for(j=m-z(m-i),s+=(t+=a=(m%2^z(m+.5-i)%2-.5)*-2+1)+'To'+(t-a)+'|';j--;)s+=(t+=a=i%2*4-2)+'To'+(t-a)+'|';alert(s)

2:

z=Math.abs;t=m=prompt(o=[])/2;t++;for(s=i='';i++<m*2;)for(j=m-z(m-i),o.push((z(m+.5-i)%2-.5)?-1:1);j--;)o.push(i%2?2:-2);o.map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

1:

t=m=prompt(o=[])/2+1;for(s=i='';++i<m;)for(j=i,o.push(i%2?-1:1);j--;)o.push(i%2?2:-2);o.concat(o.slice().reverse().slice(m-1)).map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

Dies verwendet das Konzept, dass das Muster gespiegelt wird:

Key
R='Jump Right'
r='Shift Right'
L='Jump Left'
l='Shift Left'
m='Move'
j='Jump'

Also, wo n=2ist das Bewegungsmuster:

rLr
mjm

Welches entspricht

+1 -2 +1

Dieses Muster wiederholt sich wie folgt ( n=8)

rLlRRrLLLlRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjmjjmjm
+1 -2 -1 +2 +2 +1 -2 -2 -2 -1 +2 +2 +2 +2 -1 -2 -2 -2 +1 +2 +2 -1 -2 +1

Wir können hier einige Muster feststellen:

  1. Die Bewegung wechselt zwischen links und rechts
  2. Die Anzahl der Bewegungen in einer bestimmten Richtung erhöht sich von 1 auf n/2, was sich dreimal wiederholt, und verringert sich dann wieder auf 1.
  3. Die Art der Bewegung wechselt zwischen Verschieben und Springen, wobei die Anzahl der Verschiebungen in einer Reihe konstant 1ist und die Anzahl der aufeinanderfolgenden Sprünge von 1 auf 1 n/2sinkt.
  4. Die Summe der Bewegungen ist immer 0. (Nicht sicher, ob dies tatsächlich relevant ist)

n=14::

rLlRRrLLLlRRRRrLLLLLlRRRRRRrLLLLLLLrRRRRRRlLLLLLrRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjjjmjjjjjjmjjjjjjjmjjjjjjmjjjjjmjjjjmjjjmjjmjm

Beispielausgabe:

f(2)::

1To2|3To1|2To3| 

f(8)::

4To5|6To4|7To6|5To7|3To5|2To3|4To2|6To4|8To6|9To8|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|7To8|5To7|3To5|4To3|6To4|5To6|

f(40)::

20To21|22To20|23To22|21To23|19To21|18To19|20To18|22To20|24To22|25To24|23To25|21To23|19To21|17To19|16To17|18To16|20To18|22To20|24To22|26To24|27To26|25To27|23To25|21To23|19To21|17To19|15To17|14To15|16To14|18To16|20To18|22To20|24To22|26To24|28To26|29To28|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|12To13|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|31To30|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|10To11|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|33To32|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|8To9|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|35To34|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|6To7|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|37To36|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|4To5|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|39To38|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|2To3|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|41To40|39To41|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|39To40|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|4To3|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|37To38|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|6To5|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|35To36|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|8To7|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|33To34|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|10To9|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|31To32|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|12To11|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|29To30|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|14To13|16To14|18To16|20To18|22To20|24To22|26To24|28To26|27To28|25To27|23To25|21To23|19To21|17To19|15To17|16To15|18To16|20To18|22To20|24To22|26To24|25To26|23To25|21To23|19To21|17To19|18To17|20To18|22To20|24To22|23To24|21To23|19To21|20To19|22To20|21To22|

Hier ist ein Pseudocode, um die Methode zu demonstrieren:

var mid=cursor=N/2,delta
cursor++                 // the cursor is where the empty space is.
for(i=0; i++<N;){
  delta = (mid%2^abs(mid+.5-i)%2-.5)*-2+1;  // 1 or -1
  print((cursor+delta) + 'To' + cursor + '|')
  cursor+=delta
  for(j=mid-abs(mid-i);j--;)
  {
    delta = i%2*4-2  // 2 or -2
    print((cursor+delta) + 'To' + cursor + '|')
    cursor+=delta
  }
}
Shmiddty
quelle
2
Sie haben Recht, dass das Muster mit l/L/r/Rund klarer ist m/j. Ich mag die Idee, die Distanz von der Richtung zu trennen
Gordon Bailey
2

C - 216 213

Meine Lösung basiert auf zwei Fakten:

  1. Das Feld "bis" ist das Feld "von" des vorherigen Zugs (da Sie in dem Feld, aus dem Sie sich bewegen, immer einen leeren Platz erstellen und immer zu einem leeren Platz wechseln).

  2. Die Entfernungen und Richtungen, die bewegt werden, weisen ein sehr regelmäßiges Muster auf. Für die ersten 3 Testfälle sind dies:

    1 -2 1

    1 -2 -1 2 2 -1 -2 1

    1 -2 -1 2 2 1 -2 -2 -2 1 2 2 -1 -2 1

In diesem Sinne habe ich im Grunde nur ein Programm geschrieben, um dieses Muster zu produzieren und fortzusetzen. Ich bin mir ziemlich sicher, dass es eine wirklich schöne und viel elegantere rekursive Art geben muss, dies zu schreiben, aber ich habe es noch nicht herausgefunden:

#include <stdio.h>

int main(int argc, const char *argv[])
{
   int upper_bound = atoi(argv[1]) / 2;
   int len;
   int from;
   int to = upper_bound + 1;
   int direction = 1;
   int i;

   for(len = 1; len <= upper_bound; ++len){
      for(i = len-1; i >=0; --i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   for(i=1; i < len; ++i){
      from = to - direction*2;
      printf("%02dTo%02d|",from,to);
      to = from;
   }
   direction*=-1;
   for(--len; len >= 0; --len){
      for(i = 0; i < len; ++i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   return 0;
}

Und Golf gespielt (obwohl dies eine Code-Herausforderung war, kein Golf):

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U,char**A){U=atoi(A[1])/2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U){scanf("%d",&U);U/=2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}
Gordon Bailey
quelle
Wenn ich Ihre Golfversion betreibe, bekomme ich einen Segfault.
artistoex
Oh, tut mir leid, ich habe vergessen zu erwähnen, dass die Eingabe als Befehlszeilenargument angegeben wird. Wenn Sie sie ohne Argumente ausführen, tritt ein Segfault auf. Aber jetzt, wo Sie es erwähnen, weiß ich nicht, warum ich dachte, Befehlszeilenargumente wären kürzer als scanf. Ich aktualisiere meine Antwort mit einer besseren Version.
Gordon Bailey
Das Muster ist mehr bemerkbar , wenn Sie verwenden L / R / L / R (großes Wesen "Sprung"): N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLretc.
Shmiddty
2

Mathematica

Dieser Ansatz erstellt eine Nested-Sequenz der Größe und Richtung der Bewegungen, die {fromPosition,toPosition}beginnend mit der Position formatiert nist und nsich auf die Anzahl der Übereinstimmungspaare bezieht. Es ist dann Folddie Sequenz in eine Funktion, die mit dem Verschieben beginnt {n, n+1}.

z@n_:=(p=1;h@t_:=Append[{Table[2 (-1)^t,{t}]},{(-1)^(t+1)}];
k=Join[Reverse@Drop[#,n],#]&[Flatten@Nest[Prepend[#,h[p++]]&,{},n]];
Fold[Append[#,{#[[-1,1]]-#2,#[[-1,1]]}]&,{{n,n+k[[1]]}},Rest@k])

z[1]

{{1, 2}, {3, 1}, {2, 3}}


z[4]

{{4, 5}, {6, 4}, {7, 6}, {5, 7}, {3, 5}, {2, 3}, {4, 2}, {6, 4}, { 8, 6}, {9, 8}, {7, 9}, {5, 7}, {3, 5}, {1, 3}, {2, 1}, {4, 2}, {6, 4}, {8, 6}, {7, 8}, {5, 7}, {3, 5}, {4, 3}, {6, 4}, {5, 6}}


z[7]

{{7, 8}, {9, 7}, {10, 9}, {8, 10}, {6, 8}, {5, 6}, {7, 5}, {9, 7}, { 11, 9}, {12, 11}, {10,12}, {8, 10}, {6, 8}, {4, 6}, {3, 4}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, {13, 11}, {14, 13}, {12, 14}, {10, 12}, {8, 10}, {6, 8} , {4, 6}, {2, 4}, {1, 2}, {3, 1}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, { 13, 11}, {15, 13}, {14, 15}, {12, 14}, {10, 12}, {8, 10}, {6, 8}, {4, 6}, {2, 4}, {3, 2}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, {13, 11}, {12, 13}, {10, 12} , {8, 10}, {6, 8}, {4, 6}, {5, 4}, {7, 5}, {9, 7}, {11, 9}, {10, 11}, { 8, 10}, {6, 8}, {7, 6}, {9, 7}, {8, 9}}


Visualisierung der Swaps

r,, bund osind Bilder oder eine rote Übereinstimmung, eine blaue Übereinstimmung bzw. keine Übereinstimmung.

Streichhölzer

Im Folgenden wird die Ausgabe von formatiert z, um die Swaps mit Übereinstimmungen anzuzeigen.

swaps[n_]:=FoldList[Grid[{Permute[#[[1,1]],Cycles[{#2}]],Range[2n+1]}]&,
Grid[{Join[Table[r,{n}],{o},Table[b,{n}]],Range[2n+1]}],z[n]]

swapMatches[n_]:=Grid[Partition[swaps[n],2,2,1,""],Dividers->All]

swapsErzeugt eine Liste von Zuständen, indem die geordneten Paare von zas-Befehlen verwendet werden, um die anfängliche Liste und nachfolgende Listen zu permutieren.

swaps[1]

Swaps1

swapMatches Zeigt die Zustände in einem Raster an.

swapMatches[2]

swaps2

swapMatches[3]

swaps3

DavidC
quelle
0

Javascript 191

function f(N) {
    n=N>>=i=c=a='1';n++
    s=z='0'
    for(k=b='34';i<N;k=i%2?a+=z+z:b+='44',i++)c=k+c
    t=''
    i=N*(N+1)/2
    l=2*i+N
    for(;l;n+=(i>=1?r=c[i-1]:i<=-N?c[-i-N]:k[1])-2,t+=(s=n>9?'':z)+n+a+'|',--l,--i)a='To'+s+n
    return t
}

Zeichen gezählt mit grep =|tr -d \ |wc -c

artistoex
quelle
1
Hallo und willkommen bei Codegolf! Ich denke, Sie werden feststellen, dass Ihre Lösung für keinen der Testfälle ( jsfiddle.net/SJwaU ) die richtige Ausgabe liefert . Für die Eingabe 02sind die Werte korrekt, es fehlt jedoch die nachfolgende |. In den beiden anderen Fällen sind die Werte weit entfernt und die Formatierung von 10ist ebenfalls falsch. Auch nicht sicher über Ihre Charakterzählmethode. Warum zählen Sie nur den Funktionskörper abzüglich der Rendite?
Gordon Bailey
@gordon Ups, anscheinend habe ich bei meiner letzten Optimierung einen Fehler gemacht. Vielen Dank für den Hinweis. Ich zähle den Körper nur, weil auf einer REPL das alles ist, was Sie brauchen. Ich habe die Funktionsdekoration nur der Einfachheit halber angebracht.
artistoex
Sie müssen relevante Leerzeichen (z. B. Zeilenumbrüche) für Ihre Gesamtsumme zählen.
Shmiddty
@shmiddty tr -d \ |wc -cberücksichtigt Zeilenumbrüche
artistoex