Échange de numéros [fermé]

10

Il s'agit d'un casse-tête courant que beaucoup d'entre vous ont résolu manuellement. Maintenant, c'est le moment d'écrire un algorithme pour résoudre le même.

Il y a des bâtons de match de nombre égal alignés sur deux côtés différents face à face. Il y a un seul espace vide entre eux. Dites quelque chose comme la figure suivante (si le nombre total de bâtons de match est de 4).

entrez la description de l'image ici

Chaque bâton peut soit glisser d'un pas vers l'avant (si l'espace avant immédiat est libre), soit sauter par-dessus un bâton à l'avant et atterrir dans l'espace libre (si cet espace est libre). Le déplacement en sens inverse n'est pas possible (même l'espace est libre). Aucun saut inversé n'est également autorisé. Un seul mouvement est autorisé en une seule étape.

Maintenant, vous devez écrire un algorithme pour trouver les étapes minimales requises à l'aide desquelles tous les bâtons de match de gauche se poseront du côté droit et tous les sticks de match du côté droit se poseront du côté gauche.

Par exemple: s'il y a au total 2 bâtons de match (1 de chaque côté), les étapes seront les suivantes:

entrez la description de l'image ici

Remarque: Dans la figure ci-dessus, le manche gauche a été déplacé en premier. Une autre solution existe lorsque le manche droit se déplace en premier. Mais pour ce problème, vous devez donner une seule solution et cela suppose également que le stick latéral gauche se déplace en premier.

La figure suivante décrit les mouvements avec 4 bâtons de match (2 de chaque côté):

entrez la description de l'image ici

Remarque: Dans la figure ci-dessus, le manche gauche a été déplacé en premier. Une autre solution existe lorsque le manche droit se déplace en premier. Mais pour ce problème, vous devez donner une seule solution et cela suppose également que le stick latéral gauche se déplace en premier.

[Hypothèse: L'entrée peut être n'importe quel nombre pair entre 02 et 14 (c'est-à-dire 1 à 7 allumettes de chaque côté). Pour les entrées en dehors de cette plage, vous n'avez pas besoin d'effectuer de validation, ni de fournir de message d'erreur. Remarque: Dans la sortie, chaque étape est séparée par un «|» (pipe). Les programmeurs COBOL doivent toujours supposer que PIC 9 (2) est la taille d'entrée et peuvent également supposer que la sortie doit être d'une longueur maximale fixe de 450 caractères, avec des espaces à droite.]


Exemple d'entrée:

02  

Exemple de sortie:

01To02|03To01|02To03|


Exemple d'entrée:

04  

Exemple de sortie:

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


Exemple d'entrée:

06  

Exemple de sortie:

03To04|05To03|06To05|04To06|02To04|01To02|03To01|05To03|07To05|06To07|04To06|02To04|03To02|05To03|04To05|
user2076421
la source
Si vous ne pouvez pas inclure les images directement, pouvez-vous fournir des liens pour que quelqu'un d'autre puisse les modifier?
Peter Taylor
2
J'ai fait quelques images rapides. J'espère qu'ils sont conformes à l'intention de l'auteur d'origine.
primo
3
Condition de victoire?
Shmiddty

Réponses:

3

APL 129

Le code ci-dessous prend l'entrée et les sorties d'écran à l'écran dans le format spécifié:

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)),¨⊂'|')~' '

Un bon tiers du code est utilisé pour formater la sortie. La logique est complétée par l'occurrence du symbole ⋄ dans le code.

Voici le résultat pour une entrée de 08 comme vérification:

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
la source
1
J'ai toujours l'impression
qu'APL
@Shmiddty J'ai peur que tout langage purement basé sur des symboles tels que APL, J, GolfScript, etc. gagnera très probablement du golf de code contre des langages basés sur des mots plus verbeux;)
Graham
3

Javascript 178 174 161

prompts pour nensuite alerts réponse. (Pas de 0rembourrage)

Dernier:

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)

Cela utilise le concept que le modèle est mis en miroir:

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

Alors, où n=2, le modèle de mouvement est:

rLr
mjm

Ce qui équivaut à

+1 -2 +1

Ce modèle se répète comme tel ( 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

Nous pouvons remarquer quelques modèles ici:

  1. Le mouvement alterne entre gauche et droite
  2. Le nombre de mouvements dans une direction particulière passe de 1 à n/2, qui se répète 3 fois, puis redescend à 1.
  3. Le type de mouvement alterne entre le décalage et le saut, le nombre de changements dans une rangée étant une constante 1et le nombre de sauts séquentiels augmentant de 1 à n/2puis diminuant de nouveau à 1.
  4. La somme des mouvements est toujours 0. (Je ne sais pas si cela est réellement pertinent)

n=14:

rLlRRrLLLlRRRRrLLLLLlRRRRRRrLLLLLLLrRRRRRRlLLLLLrRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjjjmjjjjjjmjjjjjjjmjjjjjjmjjjjjmjjjjmjjjmjjmjm

Exemple de sortie:

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|

Voici un pseudo-code pour illustrer la méthode:

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
la source
2
Vous avez raison de dire que le motif est plus clair avec l/L/r/Ret m/j. J'aime l'idée de séparer la distance déplacée de la direction
Gordon Bailey
2

C - 216 213

Ma solution repose sur deux faits:

  1. Le champ "à" est le champ "à partir de" du mouvement précédent (puisque vous créez toujours un emplacement vide dans l'espace d'où vous vous déplacez et que vous vous déplacez toujours vers un emplacement vide)

  2. Les distances et les directions qui sont déplacées sont très régulières. Pour les 3 premiers cas de test, ce sont:

    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

Dans cet esprit, j'ai simplement écrit un programme pour produire et continuer ce modèle. Je suis presque sûr qu'il doit y avoir une manière récursive vraiment belle et beaucoup plus élégante d'écrire ceci, mais je ne l'ai pas encore compris:

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

Et joué au golf (même s'il s'agissait d'un défi de code, pas de 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
la source
Lorsque je lance votre version golfée, je reçois un défaut de segmentation.
artistoex
Oh désolé, j'ai oublié de mentionner que l'entrée est donnée en tant qu'argument de ligne de commande - si vous l'exécutez sans arguments, cela provoquera une erreur de segmentation. Mais en fait maintenant que vous le mentionnez, je ne sais pas pourquoi je pensais que les arguments de la ligne de commande seraient plus courts que scanf. Je mets à jour ma réponse avec une meilleure version.
Gordon Bailey
Le modèle est plus visible lorsque vous utilisez L / R / l / r (grand être "saut"): N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLr, etc.
Shmiddty
2

Mathematica

Cette approche construit une Nestséquence ed de la taille et de la direction des mouvements, formatée en {fromPosition,toPosition}commençant par la position n, où se nréfère au nombre de paires de correspondances. Il s'agit ensuite de Foldla séquence en une fonction qui commence par le mouvement {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}}


Visualisation des swaps

r,, bet osont des images ou une correspondance rouge, une correspondance bleue et aucune correspondance, respectivement.

allumettes

Les formats suivants formatent la sortie de zpour afficher les échanges avec des correspondances.

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]

swapsproduit une liste d'états en utilisant les paires ordonnées de zcommandes as pour permuter la liste initiale et les listes suivantes.

swaps[1]

swaps1

swapMatches affiche les états dans une grille.

swapMatches[2]

swaps2

swapMatches[3]

swaps3

DavidC
la source
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
}

Caractères comptés avec grep =|tr -d \ |wc -c

artistoex
la source
1
Salut et bienvenue sur codegolf! Je pense que vous constaterez que votre solution ne produit la sortie correcte pour aucun des cas de test ( jsfiddle.net/SJwaU ). Pour l'entrée 02, les valeurs sont correctes, mais il manque la fin |. Pour les deux autres cas, les valeurs sont loin et la mise en forme de 10est également incorrecte. Pas sûr non plus de votre méthode de comptage de caractères. Pourquoi comptez-vous seulement le corps de la fonction moins le retour?
Gordon Bailey
@gordon Oups, il semble que j'ai fait une erreur dans ma dernière optimisation. Merci de l'avoir signalé. Je compte le corps uniquement parce que sur un REPL, c'est tout ce dont vous avez besoin. J'ai mis la décoration de fonction uniquement pour des raisons de commodité.
artistoex
Vous devez compter les espaces pertinents (par exemple, les nouvelles lignes) dans votre total.
Shmiddty
@shmiddty tr -d \ |wc -cprend en compte les nouvelles lignes
artistoex