Kettenwortkreuzworträtselart


18

Die Herausforderung

Bei einer gegebenen Liste von Wörtern ["Programming", "Puzzles", "Code", "Golf"]wird der Wortkreuzworträtselstil ausgegeben:

      Programmierung
      u
      z
      z
  G l
C ode
  ls
  f

Der Algorithmus

  • Sie müssen die Liste in der angegebenen Reihenfolge bearbeiten.
  • Die Wörter werden abwechselnd horizontal gedruckt .
  • Die beiden Wörter kreuzen sich beim ersten Buchstaben im ersten Wort, der auch im zweiten Wort vorhanden ist. Wenn dieser Buchstabe im zweiten Wort mehrmals vorkommt, nehmen Sie den ersten.

    Beispiel :
    ["no", "on"]wird:

    o
    n o
    

    und nicht

    n o
      n
    

Zusätzliche Bemerkungen

  • Benachbarte Wörter in der Liste haben mindestens einen gemeinsamen Buchstaben. ["Hi", "there"]ist keine gültige Eingabe.
  • Worte werden niemals kollidieren. Es ist immer genügend Platz vorhanden, um ein Wort an der ersten möglichen Kreuzung zu drucken. ["Hello", "there", "end", "hello"]ist keine gültige Eingabe
  • Bei der Zuordnung wird zwischen Groß- und Kleinschreibung unterschieden.
  • Wörter können nach links und oben erweitert werden.
  • Die Buchstaben der horizontalen Wörter müssen durch ein Leerzeichen getrennt werden.
  • Die Eingabeliste enthält mindestens zwei Wörter.
  • Alle Wörter stimmen mit dem regulären Ausdruck überein: [A-Za-z]+
  • Sie können so viele nachgestellte Leerzeichen oder Zeilenumbrüche drucken, wie Sie möchten, solange die Wörter korrekt verkettet sind.
  • Auf der anderen Seite können Sie möglicherweise keine weiteren führenden Leerzeichen hinzufügen. Das Wort, das am weitesten links schwebt, hat null führende Leerzeichen, die anderen Zeilen haben so viele führende Leerzeichen, dass alle richtig ausgerichtet sind.
  • Ihr Programm muss mit einer beliebigen Anzahl von Wörtern umgehen können

Regeln

  • Funktion oder Vollprogramm erlaubt.
  • Standardregeln für die Eingabe / Ausgabe.
  • Es gelten Standardlücken .
  • Dies ist , also gewinnt die niedrigste Byte-Anzahl. Tiebreaker ist eine frühere Vorlage.

Testfälle

Eingabeliste in der ersten Zeile, Ausgabe beginnt in der zweiten Zeile.

["Stack", "Exchange"]
    E
    x
    c
    h
Stapel
    n
    G
    e
["This", "site", "graduated", "finally"]
    f
    ist
    n D as
absolvierte
    le
    l
    y


Viel Spaß beim Codieren!


Beispiel 2, der erste mögliche Schnittpunkt zwischen siteund graduatedistt
edc65

@ edc65 Schande über mich, habe es behoben. Danke für den Tipp!
Denker

Antworten:


3

JavaScript (ES6) 253

Als anonyme Funktion mit einem Array-Parameter

z=>(z.map((w,i)=>(i&&[...p].some((c,j)=>~(k=w.search(c))?i&1?[y-=k,x+=j]:[y+=j,x-=k]:0),[p=w,x<t?t=x:x,y<u?u=y:y]),t=u=x=y=0).map(([w,x,y],i)=>{x-=t,y-=u;for(c of w)(o[y]=o[y]||[])[x]=c,i&1?y++:x++},o=[]),o.map(r=>[...r].map(x=>x||' ').join` `).join`
`)

F=z=>(z.map((w,i)=>(i&&[...p].some((c,j)=>~(k=w.search(c))?i&1?[y-=k,x+=j]:[y+=j,x-=k]:0),[p=w,x<t?t=x:x,y<u?u=y:y]),t=u=x=y=0).map(([w,x,y],i)=>{x-=t,y-=u;for(c of w)(o[y]=o[y]||[])[x]=c,i&1?y++:x++},o=[]),o.map(r=>[...r].map(x=>x||' ').join` `).join`
`)

// Less golfed
F=z=>(
  z.map( // Step 1, find intersection points and relative position
    (w,i)=>(
      i && // for each word after thw first, find position respect the previous word
      [...p].some((c,j)=> // scan prec word using .some to exit at the first intersection found
         ~(k=w.search(c)) // search current char of p inside w
         ?i&1 // calc position, odd is vertical, even is horizontal
           ?[y-=k, x+=j] // returning an array so to have a truthy value
           :[y+=j, x-=k] // returning an array so to have a truthy value
         :0 // false = not found, continue the scan
      ),
      [p=w, // set preceding word
       x<t?t=x:x, // keep trace of min x
       y<u?u=y:y  // keep trace of min y
      ] // meanwhile, return word, x and y to be used in next step 
    ), t=u=x=y=0 // initializations
  )
  .map(([w,x,y],i)=>{ // Step 2, put char into the output array
      x-=t,y-=u; // normalize position respect to min values
      for(c of w) // for each char in word, set in the output array at the right place
        (o[y]=o[y]||[])[x]=c, 
        i&1?y++:x++ // increment x or y, again odd is vertical, even is horizontal
    }, o=[] // initialization of output array
  ),
  // Step 3, add the missing spaces and newlines
  o.map(r=>[...r].map(x=>x||' ').join` `).join`\n`
)

O.textContent=F(["This", "site", "graduated", "finally"])
<pre id=O></pre>


3

ANSI C, 385 390 Zeichen

int N,a=1,x,y,d=1,u,k,l;int main(int c,char**v){for(;a<c;)N+=strlen(v[a++]);int H=N*2,W=N*4,m=H,n=N,q=m,w=n;char*p,F[W][H],*o;memset(F,32,W*H);for(a=1;a<c;a++){q=(x=m)<q?m:q;w=(y=n)<w?n:w;m=-1;for(p=v[a];*p;p++){F[x][y]=*p;if(m<0&&a<c-1&&(o=strchr(v[a+1],*p))){u=o-v[a+1];m=d?x:x-u*2;n=d?y-u:y;}if(d)x+=2;else y++;}d=!d;}for(l=w;l<H;l++){for(k=q;k<W;)putchar(F[k++][l]);putchar(10);}}

Nenne es so: ./crossword This site graduated finally

Ungolfed-Version:

int N,a=1,x,y,d=1,u,k,l;
int main(int c, char **v) {
    for(;a<c;)
        N+=strlen(v[a++]);
    int H = N*2, W = N*4, m = H, n = N, q=m, w=n;
    char *p,F[W][H], *o;
    memset(F, 32, W*H);
    for (a=1; a < c; a++) {
        q=(x=m)<q?m:q;
        w=(y=n)<w?n:w;
        m=-1;
        for (p=v[a]; *p; p++) {
            F[x][y] = *p;
            if (m<0&&a<c-1&&(o = strchr(v[a+1], *p))) {
                u = o-v[a+1];
                m = d ? x : x-u*2;
                n = d ? y-u : y;
            }
            if (d) x+=2; else y++;
        }
        d=!d;
    }
    for (l = w; l < H; l++) {
        for (k = q; k < W;)
            putchar(F[k++][l]);
        putchar(10);
    }
}

Danke tucuxi für die Tipps!


one char: a++)N+=strlen(v[a])=>)N+=strlen(v[a++])
tucuxi

ein anderes: char F[W][H],*p=>char*p,F[W][H]
tucuxi

3 Zeichen: Entfernen {} von einzeiligen forErsetzen k++)putchar(F[k][l]mit)putchar[k++][l]
tucuxi
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.