Raggruppa i numeri con la stessa somma


12

Il tuo compito è, data una griglia quadrata di cifre ( 0-9), generare uno dei modi in cui le cifre possono essere raggruppate in modo tale che:

  1. Ogni cifra fa parte esattamente di un gruppo
  2. Tutti i gruppi hanno lo stesso numero di cifre
  3. Tutti i gruppi sono delimitati da una forma simile a un poligono (ciò significa che ogni cifra nel gruppo è accanto a [sinistra, destra, su, giù] almeno un'altra cifra dello stesso gruppo, a meno che ogni gruppo abbia 1 elemento).
  4. Tutti i gruppi hanno la stessa somma

La griglia di input sarà sempre un quadrato: puoi scegliere qualsiasi metodo di input che desideri (incluso fornire argomenti a una funzione o metodo). Inoltre, l'input fornirà il numero di gruppi in cui il programma dovrebbe raggruppare le cifre.

Esempio di input:

Supponiamo che il tuo formato di input sia stringOfDigits numberOfGroups.

Un input di esempio potrebbe essere:

156790809 3

che si tradurrebbe in (una griglia di sqrt(9) * sqrt(9))

1 5 6
7 9 0
8 0 9

che dovresti dividere in 3 gruppi, ognuno dei quali dovrebbe avere 9 / 3 = 3elementi con la stessa somma.

Output: l'output dovrebbe essere la stringa di cifre, con spazi opzionali e nuove righe per la formattazione, con ogni cifra seguita da una lettera che a-zindica il suo gruppo. Dovrebbero esserci esattamente numberOfTotalDigits / numberOfGroupselementi in ciascun gruppo. Non dovrai mai dividere qualcosa in più di 26 gruppi.

Esempio di output:

1a 5a 6b
7c 9a 0b
8c 0c 9b

Nota che la sostituzione di tutti as con bs e bs con as è ugualmente valido. Finché ogni gruppo è indicato da una lettera distinta, l'output è valido.

Inoltre, mi aspetto che la maggior parte dei programmi produca qualcosa di simile a questo, perché le nuove righe / spazi sono opzionali:

1a5a6b7c9a0b8c0c9b

In questo caso, aggiungendo tutte le cifre del gruppo a, bo ccrea 15. Inoltre, tutti i gruppi sono associati da un poligono.

Uscite non valide:

1a 5a 6b
7c 9a 0c
8c 0b 9b

perché i gruppi non formano poligoni (in particolare, 6bè isolato ed 0cè anche solo).

1a 5a 6b
7c 9a 0b
8c 0b 9b

perché il gruppo bha 4 elementi mentre cne ha solo 2.

Eccetera.

Se non esiste una soluzione valida, il tuo programma potrebbe fare qualsiasi cosa (es. Arresto, arresto anomalo, esecuzione per sempre) ma se il tuo programma stampa Nonequando non esiste una soluzione valida, -15al tuo punteggio.

Se esiste più di una soluzione, devi solo stamparne una, ma -20se il tuo programma le stampa tutte separate da un delimitatore.

Questo è il codice golf, quindi vince il codice più breve (con bonus)!


Nel primo output non valido, penso che tu voglia dire che 6bè isolato, non il 0b.
Level River St,

Importa quanto è veloce il nostro programma? Che dire se è troppo lento per convalidare se funziona?
Decadimento beta

156790889 3sembra che dovrebbe essere156790809 3
isaacg

Risposte:


10

Pyth , 122-20-20 = 87

=Z/lzQ=ks^lz.5Jm]dUzL[-bk+bk?tb%bkb?hb%hbkb)FNJIgNZB~Jm+NksmybN;|jbS{msm+@zk@S*Z<GQxsdkUzfqSsTUz^fqsmv@*ZzbY/smvdzQJQ"None

I cambiamenti:

  • 130 -> 120: commutato su newline input separato.

  • 120 -> 134: corretto un bug relativo a gruppi di dimensioni non uguali alla lunghezza laterale della matrice.

  • 134 -> 120: stampa tutte le soluzioni, comprese quelle equivalenti con la ridenominazione di gruppo.

  • 120 -> 122: corretto un bug in cui venivano generati solo i percorsi, anziché tutti i gruppi legali.

Prova:

pyth programs/sum_group.pyth <<< '156790809
3'
1a5a6b7c9a0b8c0c9b
1a5a6c7b9a0c8b0b9c
1b5b6a7c9b0a8c0c9a
1b5b6c7a9b0c8a0a9c
1c5c6a7b9c0a8b0b9a
1c5c6b7a9c0b8a0a9b


pyth programs/sum_group.pyth <<< '156790808
3'
None

pyth programs/sum_group.pyth <<< '1111     
2'
1a1a1b1b
1a1b1a1b
1b1a1b1a
1b1b1a1a

Spiegazione:

Pyth code           (Pseudo)-Python code              Comments

(implicit)          z = input()                       z is the digit string
(implicit)          Q = eval(input())                 S is the number of groups
(implicit)          G = 'abcdefghijklmnopqrstuvwxyz'
=Z/lzQ              Z = len(z)/Q                      Z is the size of each group.
=ks^lz.5            k = int(len(z) ** .5)             k is the side length of the matrix.
Jm]dUz              J = map(lambda d:[d], range(len(z))) Locations are encoded as numbers.
L                   def y(b): return                  y will be the transition function.
 [-bQ                         [b-k,                   Move up - the row above is k less.
  +bQ                          b+k,                   Move down - the row below is k more.
  ?tb%bkb                      b-1 if b%k else b      Move left, unless at the left edge.
  ?hb%hbkb)                    b+1 if (b+1)%k else b] Move right, unless at right edge.
FNJ                 for N in J:                       This constructs the list of all
   IgNZB                       if N[Z-1]: break       Z-length connected groups.
   ~Jm+Nk                      J+=map(lambda k: N+[k],  Append to J the group of N +
      smybN                          sum(map(lambda b:  anything reachable from
                                     y(b),N)))        anywhere in N.
   ;                (end for)
|                   or                                Print first truthy thing between
 S{                 sorted(set(                       Unique elements in sorted order of
   ms               map(lambda b:sum(                 Map+sum over allowable combinations
     m+@zd          map(lambda d:z[d]+                Character in original digit string
       @S*Z<GQ      sorted(G[:Q]*Z)[                  Repeated and sorted early alphabet
        xsbd        sum(b).index(d)],                 At index of number in sum of groups
      Uz                range(len(z)))                Over possible indexes.
   f                filter(lambda T:                  To generate allowable combinations, 
                                                      we will filter all groups of Q paths.
    qSsTUz          sorted(sum(T)) == range(len(z))   Ensure all locations are visited.
    ^                                                 Combinations of
     f              filter(lambda Y:                  Filter over connected Z-length groups
      qsm           equal(sum(map(lambda k:           Sum of the values of the group
         v@*ZzkY    eval((z*Z)[k]),Y)                 In the original digit string
       /smvbzQ      sum(map(lambda b:eval(b),z))/Q    must equal the sum of all values in z
                                                      divided by the number of groups.
      J             J                                 Filter over connected Z-length groups
     Q              Q                                 Combinations of length Q
 "None              "None"                            If the above was empty, print "None"

9
"Pyth"? Hai sbagliato a scrivere "base64".
Ingo Bürk,

4

JavaScript (ES6) 361 (376-15) 372

(Forse si può ancora giocare a golf un po 'di più)

Come funzione, il primo parametro è la stringa di cifre e il secondo parametro è il numero di gruppi.
È una ricerca ricorsiva ingenua, che si ferma alla prima soluzione trovata (nessun bonus di -20).
Sono necessari altri casi di test per verificare le prestazioni su input più grandi.

F=(g,n,l=g.length,i=w=Math.sqrt(l),o=s=h='',
  R=(g,p,k,j=l/n,t=s/n,v=0,h=String.fromCharCode(97+k))=>(
    t-=g[p],!(t<0)&&(
      g=[...g],g[p]=h,
      S=f=>g.some((c,p)=>c<':'&&f(p)),
      --j?S(p=>(g[p+1]==h|g[p-1]==h|g[p+w+1]==h|g[p-w-1]==h)?v=R(g,p,k,j,t):0)
      :t?0:k?S(p=>v=R(g,p,k-1)):v=g
    ),v
  )
)=>([for(c of g)(s-=-c,h+=--i?c:(i=w,c+':'))],h=R(g=h,-1,n,1))?h.map((c,p)=>o+=c!=':'?g[p]+c:'')&&o:'None'

Ungolfed e spiegato

F=(g,n)=> 
{
  var l = g.length, // string size, group size is l/n 
      w = Math.sqrt(l), // width of grid
      s,i,h,o;

  // Build a new string in h, adding rows delimiters that will act as boundary markers  
  // At the same time calculate the total sum of all digits
  h='',  // Init string
  s = 0, // Init sum 
  i = w, // Init running counter for delimiters
  [for(c of g)(
    s -= -c, // compute sum using minus to avoid string concatenation
    h += --i ? c : (i=w, c+':') // add current char + delimiter when needed
  )];


  // Recursive search
  // Paramaters:
  // g : current grid array, during search used digits are replaced with group letters
  // p : current position
  // k : current group id (start at n, decreaseing)
  // j : current group size, start at l/n decreasing, at 0 goto next group id
  // t : current group sum value, start at s/n decreasing

  var R=(g,p,k,j,t)=> 
  {
    var v = 0, // init value to return is 0
        h = String.fromCharCode(97+k); // group letter from group

    t-=g[p]; // subtract current digit

    if (t<0) // exceed the sum value, return 0 to stop search and backtrak
      return 0;

    g=[...g]; // build a new array from orginal parameter
    g[p] = h; // mark current position

    // Utility function  to scan grid array
    // call worker function  f only for digit elements
    //   skipping group markers, row delimieters and out of grid values (that are undefined)  
    // Using .some will return ealry if f returns truthy  
    var S=f=>g.some((c,p)=>c<':'&&f(p));

    if (--j) // decrement current group size, if 0 then group completed
    { // if not 0
      // Scan grid to find cells adiacent to current group and call R for each 
      S( p => {
        if (g[p+1]==h|g[p-1]==h|g[p+w+1]==h|g[p-w-1]==h) // check if adiacent to a mark valued h
        {
          return v=R(g,p,k,j,t) // set v value and returns it
        }
      })
      // here v could be 0 or a full grid 
    }
    else
    {
      // special case: at first call, t is be NaN because p -1 (outside the grid)
      // to start a full grid serach
      if (t) // check if current reached 0
        return 0; // if not, return 0 to stop search and backtrak


      if (k) // check if current group completed
      {
        // if not at last group, recursive call to R to check next group 
        S( p => {
          // exec the call for each valid cell still in grid
          // params j and t start again at init values
          return v=R(g,p,k-1,l/n,s/n) // set value v and returns it
        })
        // here v could be 0 or a full grid 
      }
      else
      {
        return g; // all groups checked, search OK, return grid with all groups marked
      }
    }
    return v
  };
  g = h; // set g = h, so g has the row boundaries and all the digits

  h=R(h,-1,n,1); // first call with position -1 to and group size 1 to start a full grid search

  if (h) // h is the grid with group marked if search ok, else h is 0
  {
    o = ''; // init output string
    // build output string merging the group marks in h and the original digits in g
    h.map( (c,p) => o += c>':' ? g[p]+c: '') // cut delimiter ':'
    return o;
  }
  return 'None';
}

Test nella console FireFox / FireBug

F("156790809",3) produzione 1c5c6b7a9c0b8a0a9b

F("156790819",3) produzione None

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.