Quine N-regina-ed-equina


21

Esiste una variante del noto problema delle regine N che coinvolge regine e cavalieri e si dice che sia "considerevolmente più difficile" 1 . La dichiarazione del problema è la seguente:

Devi posizionare un numero uguale di cavalieri ♞ e regine ♛ su una scacchiera in modo tale che nessun pezzo attacca altri pezzi. Qual è il numero massimo di pezzi che puoi posizionare sulla scacchiera e in quanti modi diversi puoi farlo?

In questa sfida di , ti verrà dato un input n tra 3 e 32 (in un modo che sia il più adatto alla tua lingua). Per una data n , potrebbero esserci zero o più soluzioni al problema precedente. Nel caso in cui non ci sia soluzione, è necessario generare / restituire nulla ( zero , stringa vuota , falsa , ...). Altrimenti, devi dare due risultati:

  1. Una scheda soluzione (vedi sotto) per dimensioni n in cui non è possibile aggiungere un pezzo degli scacchi regina o cavaliere senza che un pezzo venga attaccato. Ci deve essere un numero uguale di regine e cavalieri .
  2. La fonte di un programma da eseguire che non accetta input e fornisce (i) un'altra soluzione (o nulla ) per la stessa dimensione n , nello stesso formato, nonché (ii) un altro programma per la soluzione successiva (e così via ...).

Nota che:

  • La sequenza dei programmi non deve mai restituire la stessa scheda due volte, deve coprire tutte le possibili soluzioni al problema della dimensione n e alla fine deve terminare (senza produrre output).
  • È possibile restituire due valori, restituire uno e stampare l'altro oppure stampare i due valori restituiti.
  • Tuttavia , se si stampa sia la scheda che il programma successivo, la scheda non deve essere considerata parte del programma successivo (si consiglia di stampare la scheda in commento o utilizzare sia l'output standard che i flussi di errore).
  • Il valore del programma come valore di ritorno deve essere una stringa, non una chiusura.

Formato scheda

  • Una tavola è un quadrato di dimensioni n .
  • Una cella di bordo può essere vuota, una regina o un cavaliere.
  • È necessario scegliere valori distinti per ogni tipo di cella (ovvero è possibile utilizzare simboli diversi da Q, N quando si stampa la scheda).
  • Se si restituisce una scheda non stringa, deve essere una raccolta ordinata dei n 2 valori della scheda (ad esempio matrice, vettore o elenco in ordine riga / colonna-maggiore, ...).
  • Se si stampa la scheda, è possibile stamparla al quadrato o come una linea. Ad esempio, una scheda della soluzione di dimensione 4 può essere stampata come segue (spazi non richiesti; simboli a propria discrezione):

    Q - - -
    - - - -
    - - - -
    - - N -
    

    In tal caso, puoi anche generare:

    ♛ · · ·
    · · · ·
    · · · ·
    · · ♞ ·
    

    ... ma questo è sufficiente:

    Q-------------N-
    

    Non importa se si scorre tra le celle in un ordine di riga maggiore o di colonna maggiore, poiché esistono soluzioni simmetriche. Ad esempio, le soluzioni per n = 4 sono:

    Q------N--------
    Q----------N----
    Q------------N--
    Q-------------N-
    -Q----------N---
    -Q------------N-
    -Q-------------N
    --Q---------N---
    --Q----------N--
    --Q------------N
    ---QN-----------
    ---Q----N-------
    ---Q---------N--
    ---Q----------N-
    ---NQ-----------
    ----Q------N----
    ----Q----------N
    N------Q--------
    -------QN-------
    -------Q----N---
    ---N----Q-------
    -------NQ-------
    --------Q------N
    N----------Q----
    ----N------Q----
    -----------QN---
    -N----------Q---
    --N---------Q---
    -------N----Q---
    -----------NQ---
    N------------Q--
    --N----------Q--
    ---N---------Q--
    N-------------Q-
    -N------------Q-
    ---N----------Q-
    -N-------------Q
    --N------------Q
    ----N----------Q
    --------N------Q
    

Puoi anche guardare le soluzioni per n = 5 come matrici ; le schede contengono #, qe nsimboli, che sono cellule vuote di diversi tipi (vedi la mia risposta qui di seguito). Conto 2836 schede per n = 6 , come nella risposta di Sleafar (ho introdotto un bug nel ridurre il conteggio dei byte, ma ora è stato corretto).

Mille grazie a Sleafar per aver trovato non uno ma due bug nel mio codice.

Punto

Il codice più corto in byte vince.

Misuriamo la dimensione del primo programma, quello che accetta n .


1 . Queens and Knights , di Roger KW Hui (attenzione! Contiene una soluzione)


4
Forse dovresti mettere una taglia su questo. Onestamente, il problema è abbastanza difficile senza la parte quine.
mbomb007,

Possiamo usare simboli diversi da Q, N e - per indicare Regine e Cavalieri e vuoti, purché siano distinti?
Fatalizza il

@Fatalize Sì, certo
coredump

1
@coredump Intendevo leggere il contenuto della funzione. E lo prenderò come un "sì, ti è permesso leggere il tuo codice sorgente e / o il contenuto della funzione". (La mia soluzione si basa su di essa, quindi ...)
wizzwizz4

1
@coredump Se capisco correttamente la sfida, la soluzione di riferimento per n = 6 contiene voci non valide (ad es. -------------------------N--------Q-non è valida perché è possibile aggiungere più pezzi :) Q--------N---------------N--------Q-.
Sleafar,

Risposte:


2

Groovy, 515 byte

X=0;Y="N="+args[0]+";M=N*N;S=[];def f(b,i,j,v){(i..<j).findAll{k->!(0..<M).any{l->w=b[l];r=(k.intdiv(N)-l.intdiv(N)).abs();c=(k%N-l%N).abs();s=v+w;w>0&&(k==l||(r==0||c==0||r==c?s<4:r<3&&c<3&&s>2))}}.collect{a=b.clone();a[it]=v;[it,a]}};def r(b,q,n){f(b,q,M,1).each{i->f(i[1],n,M,2).each{j->if(f(j[1],0,M,1).any{f(it[1],0,M,2)}){r(j[1],i[0],j[0])}else{S.add(j[1])}}}};r(new int[M],0,0);if(x<S.size()){sprintf('//%s%cX=%d;Y=%c%s%c;print(Eval.xy(X,Y,Y))',S[x].toString(),10,x+1,34,y,34)}else{''}";print(Eval.xy(X,Y,Y))

analisi

Fornisci n come argomento della riga di comando:

groovy qak.groovy 4

La prima riga dell'output è sempre una soluzione come commento (0 = vuoto, 1 = regina, 2 = cavaliere), seguito dal codice nella seconda riga:

//[1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]
X=1;Y="N=4;M=N*N;S=[];def f(b,i,j,v){(i..<j).findAll{k->!(0..<M).any{l->w=b[l];r=(k.intdiv(N)-l.intdiv(N)).abs();c=(k%N-l%N).abs();s=v+w;w>0&&(k==l||(r==0||c==0||r==c?s<4:r<3&&c<3&&s>2))}}.collect{a=b.clone();a[it]=v;[it,a]}};def r(b,q,n){f(b,q,M,1).each{i->f(i[1],n,M,2).each{j->if(f(j[1],0,M,1).any{f(it[1],0,M,2)}){r(j[1],i[0],j[0])}else{S.add(j[1])}}}};r(new int[M],0,0);if(x<S.size()){sprintf('//%s%cX=%d;Y=%c%s%c;print(Eval.xy(X,Y,Y))',S[x].toString(),10,x+1,34,y,34)}else{''}";print(Eval.xy(X,Y,Y))

Il seguente script può essere utilizzato per i test automatizzati (fornire nuovamente n come argomento):

#!/bin/bash
set -e
test -n "$1"
groovy qak.groovy "$1" > t
while test -s t; do
    head -n1 t
    groovy t > t2
    mv t2 t
done

Poiché ho cercato di rendere la soluzione il più piccola possibile, è molto lenta (vedi sotto per i dettagli). Ho provato solo n = 4 con questa versione per vedere se il quineification funziona.

risultati

n = 4: 40 soluzioni ( formato convertito )
n = 5: 172 soluzioni ( formato convertito )
n = 6: 2836 soluzioni ( formato convertito )

Algoritmo

Questa è una versione non quindicina leggermente non risolta della soluzione:

N=args[0] as int
M=N*N
S=[]

/**
 * Generate a list of valid posibilities to place a new piece.
 * @param b Starting board.
 * @param i Start of the index range to check (inclusive).
 * @param j End of the index range to check (exclusive).
 * @param v Value of the new piece (1=queen, 2=knight).
 * @return A pair with the index of the new piece and a corresponding board for each possibility.
 */
def f(b,i,j,v){
    (i..<j).findAll{k->
        !(0..<M).any{l->
            w=b[l]
            r=(k.intdiv(N)-l.intdiv(N)).abs()
            c=(k%N-l%N).abs()
            s=v+w
            w>0&&(k==l||(r==0||c==0||r==c?s<4:r<3&&c<3&&s>2))
        }
    }.collect{
        a=b.clone();a[it]=v;[it,a]
    }
}

/**
 * Recursively look for solutions.
 * @param b Starting board.
 * @param q Start of the index range to check for queens.
 * @param n Start of the index range to check for knights.
 */
def r(b,q,n){
    f(b,q,M,1).each{i->
        f(i[1],n,M,2).each{j->
            if(f(j[1],0,M,1).any{f(it[1],0,M,2)}){
                r(j[1],i[0],j[0])
            }else{
                S.add(j[1])
            }
        }
    }
}

r(new int[M],0,0)
S.each{println(it)}

Quineification

Ho usato un approccio molto semplice qui per mantenere basse le dimensioni del codice.

X=0;Y="...";print(Eval.xy(X,Y,Y))

La variabile X contiene l'indice della soluzione per la stampa successiva. Y contiene una copia modificata dell'algoritmo sopra, che viene utilizzato per calcolare tutte le soluzioni e quindi selezionarne solo una, motivo per cui è così lento. Il vantaggio di questa soluzione è che non richiede molto codice aggiuntivo. Il codice memorizzato in Y viene eseguito con l'aiuto della classe Eval (non è richiesto un vero quine).

Il codice modificato stampa la soluzione indicata da X , aumenta X e aggiunge una copia di se stesso:

//[...]
X=1;Y="...";print(Eval.xy(X,Y,Y))

Ho anche provato a produrre tutte le soluzioni come codice per il secondo passaggio, ma per n = 6 stava producendo troppo codice da gestire per Groovy.


Bella risposta, buon lavoro.
coredump

6

Lisp comune, 737

auto-risposta

(lambda(n &aux(d 1))#2=(catch'$(let((s(* n n))(c d))(labels((R(w % @ b ! &aux r h v a)(loop for u from % below s do(setf h(mod u n)v(floor u n)a #4=(aref b u))(when(< 0(logand a w)4)(and(= 6 w)!(throw'! t))(let((b(copy-seq b))(o 5))(loop for(K D)on'(-1 -2 -1 2 1 -2 1 2)for y =(+ K v)for x =(+(or D -1)h)for u =(and(< -1 y n)(< -1 x n)(+(* y n)x))if u do #1=(if(< #4#4)(setf #4#(logand #4#o(if(= w o)3 0)))))(#8=dotimes(y N)(#8#(x N)(let((u(+(* y n)x))(o 6))(if(or(= x h)(= y v)(=(abs(- h x))(abs(- v y))))#1#))))(setf #4#w r(or(cond((= w 5)(R 6 @ U b !))((R 5 @ U b())t)((catch'!(R 5 0 0 b t))t)(t(and(=(decf c)0)(incf d)(or(format t"~%(lambda(&aux(n ~A)(d ~A))~%~S)"n d'#2#)(throw'$ B)))t))r)))))r))(R 5 0 0(fill(make-array s)3)())))))

Esempio

Incollare quanto sopra nel REPL, che restituisce un oggetto funzione:

#<FUNCTION (LAMBDA (N &AUX (D 1))) {1006D1010B}>

Chiamalo (la stella è legata all'ultimo valore restituito):

QN> (funcall * 4)

Ciò stampa quanto segue sull'output standard:

(lambda(&aux(n 4)(d 2))
#1=(CATCH '$
 (LET ((S (* N N)) (C D))
   (LABELS ((R (W % @ B ! &AUX R H V A)
              (LOOP FOR U FROM % BELOW S
                    DO (SETF H (MOD U N)
                             V (FLOOR U N)
                             A #2=(AREF B U)) (WHEN (< 0 (LOGAND A W) 4)
                                                (AND (= 6 W) !
                                                     (THROW '! T))
                                                (LET ((B (COPY-SEQ B))
                                                      (O 5))
                                                  (LOOP FOR (K D) ON '(-1
                                                                       -2
                                                                       -1 2
                                                                       1 -2
                                                                       1 2)
                                                        FOR Y = (+ K V)
                                                        FOR X = (+
                                                                 (OR D -1)
                                                                 H)
                                                        FOR U = (AND
                                                                 (< -1 Y N)
                                                                 (< -1 X N)
                                                                 (+ (* Y N)
                                                                    X))
                                                        IF U
                                                        DO #3=(IF (< #2# 4)
                                                                  (SETF #2#
                                                                          (LOGAND
                                                                           #2#
                                                                           O
                                                                           (IF (=
                                                                                W
                                                                                O)
                                                                               3
                                                                               0)))))
                                                  (DOTIMES (Y N)
                                                    (DOTIMES (X N)
                                                      (LET ((U
                                                             (+ (* Y N) X))
                                                            (O 6))
                                                        (IF (OR (= X H)
                                                                (= Y V)
                                                                (=
                                                                 (ABS
                                                                  (- H X))
                                                                 (ABS
                                                                  (- V
                                                                     Y))))
                                                            #3#))))
                                                  (SETF #2# W
                                                        R
                                                          (OR
                                                           (COND
                                                            ((= W 5)
                                                             (R 6 @ U B !))
                                                            ((R 5 @ U B
                                                                NIL)
                                                             T)
                                                            ((CATCH '!
                                                               (R 5 0 0 B
                                                                  T))
                                                             T)
                                                            (T
                                                             (AND
                                                              (= (DECF C)
                                                                 0)
                                                              (INCF D)
                                                              (OR
                                                               (FORMAT T
                                                                       "~%(lambda(&aux(n ~A)(d ~A))~%~S)"
                                                                       N D
                                                                       '#1#)
                                                               (THROW '$
                                                                 B)))
                                                             T))
                                                           R)))))
              R))
     (R 5 0 0 (FILL (MAKE-ARRAY S) 3) NIL)))))

Inoltre, il valore restituito da questa funzione è:

#(5 0 0 0 0 0 0 6 0 0 0 2 0 2 0 0)

... che è un array letterale. Il numero 5 rappresenta le regine, 6 è per i cavalieri e qualsiasi altra cosa sta per una cella vuota, tranne che ci sono più informazioni memorizzate internamente. Se copiamo e incolliamo la funzione restituita nella sostituzione, otteniamo una nuova funzione.

#<FUNCTION (LAMBDA (&AUX (N 4) (D 2))) {100819148B}>

E possiamo chiamarlo a, senza argomenti:

QN> (funcall * )

Questa chiamata restituisce una nuova soluzione #(5 0 0 0 0 0 0 2 0 0 0 6 0 0 2 0)e l'origine di un'altra funzione (non mostrata qui). Nel caso in cui la funzione originale o l'ultima generata non trovi una soluzione, non viene stampato nulla e non viene restituito nulla.

Valori interni

|----------+--------+---------+--------+-----------------|
|          | Binary | Decimal | Symbol | Meaning         |
|----------+--------+---------+--------+-----------------|
| Empty    |    000 |       0 | -      | safe for none   |
|          |    001 |       1 | q      | safe for queen  |
|          |    010 |       2 | n      | safe for knight |
|          |    011 |       3 | #      | safe for both   |
|----------+--------+---------+--------+-----------------|
| Occupied |    101 |       5 | Q      | a queen         |
|          |    110 |       6 | K      | a knight        |
|----------+--------+---------+--------+-----------------|

Generavo troppe poche soluzioni. Propongo quale cellula è sicura per una regina e per un cavaliere, indipendentemente. Ad esempio, ecco un output per n = 5 con pretty-printing:

Q - - - - 
- - - n N 
- q - n n 
- # n - n 
- n # # - 

Quando abbiamo posizionato la regina Q, le posizioni che si allontanano da questo cavaliere sono ancora sicure per le regine e indicate q. Allo stesso modo, i cavalieri che sono raggiungibili solo dalle regine sono sicuri per altri cavalieri. I valori sono bit per bit e -ed per rappresentare le possibili mosse e alcune celle sono raggiungibili da nessun tipo di pezzo.

Più precisamente, ecco la sequenza di schede che portano alla seguente soluzione (da sinistra a destra), in cui le celle libere vengono gradualmente vincolate con valori diversi:

# # # # # #     q - - - q #     - - - - - #     - - - - - #     - - - - - n
# # # # # #     - - Q - - -     - - Q - - -     - - Q - - -     - - Q - - -
# # # # # #     q - - - q #     q - - - - -     Q - - - - -     Q - - - - -
# # # # # #     - q - q - #     - q - - - n     - - - - - n     - - - - - n
# # # # # #     # # - # # -     n n - n N -     - - - n N -     - - - - N -
# # # # # #     # # - # # #     # # - n n n     - # - - n n     - n - - n N

Approccio non quine

Versione non modificata, commentata

(defun queens-and-knights
    (n    ; size of problem
     fn   ; function called for each solution

     ;; AUX parameters are like LET* bindings but shorter.
     &aux
       ;; total number of cells in a board
       (s (* n n)))

  (labels
      ;; Define recursive function R
      ((R (w      ; what piece to place: 5=queen, 6=knight 
           %      ; min position for piece of type W
           @      ; min position for the other kind of piece
           b      ; current board
           !      ; T iff we are in "check" mode (see below)
           &aux  
           r      ; result of this function: will be "true" iff we can
                  ; place at least one piece of type W on the board b
           h      ; current horizontal position 
           v      ; current vertical position
           a      ; current piece at position (h,v)
           )

         (loop
            ;; only consider position U starting from position %,
            ;; because any other position below % was already visited
            ;; at a higher level of recursion (e.g. the second queen
            ;; we place is being placed in a recursive call, and we
            ;; don't visit position before the first queen).
            for u from % below s

            do
              (setf h (mod u n)         ; Intialize H, V and A
                    v (floor u n)       ; 
                    a (aref b u))       ; 

            ;; Apply an AND mask to current value A in the board
            ;; with the type of chess piece W. In order to consider
            ;; position U as "safe", the result of the bitwise AND
            ;; must be below 4 (empty cell) and non-null.
              (when (< 0 (logand a w) 4)

                ;; WE FOUND A SAFE PLACE TO PUT PIECE W

                (when (and ! (= 6 w))
                  ;; In "check" mode, when we place a knight, we knwo
                  ;; that the check is successful. In other words, it
                  ;; is possible to place an additional queen and
                  ;; knight in some board up the call stack. Instead
                  ;; of updating the board we can directly exit from
                  ;; here (that gave a major speed improvement since
                  ;; we do this a lot). Here we do a non-local exit to
                  ;; the catch named "!".
                  (throw '! t))

                ;; We make a copy of current board b and bind it to the
                ;; same symbol b. This allocates a lot of memory
                ;; compared to the previous approach where I used a
                ;; single board and an "undo" list, but it is shorter
                ;; both in code size and in runtime.
                (let ((b (copy-seq b)))

                  ;; Propagate knights' constraints
                  (loop
                     ;; O is the other kind of piece, i.e. queen here
                     ;; because be propagate knights. This is used as
                     ;; a mask to remove knights pieces as possible
                     ;; choices.
                     with o = 5

                     ;; The list below is arranged so that two
                     ;; consecutive numbers form a knight-move. The ON
                     ;; iteration keyword descend sublist by sublist,
                     ;; i.e. (-1 -2), (-2 -1), (-1 2), ..., (2 NIL). We
                     ;; destructure each list being iterated as (K D),
                     ;; and when D is NIL, we use value -1.
                     for (K D) on '(-1 -2 -1 2 1 -2 1 2)

                     ;; Compute position X, Y and index U in board,
                     ;; while checking that the position is inside the
                     ;; board.
                     for y = (+ K v)
                     for x = (+ (or D -1) h)
                     for u = (and (< -1 y n)
                                  (< -1 x n)
                                  (+(* y n)x))

                     ;; if U is a valid position...
                     if u
                     do
                     ;; The reader variable #1# is affected to the
                     ;; following expression and reused below for
                     ;; queens. That's why the expression is not
                     ;; specific to knights. The trick here is to
                     ;; use the symbols with different lexical
                     ;; bindings.
                       #1=(when (< (aref b u) 4) ; empty?
                            (setf (aref b u)

                                  (logand
                                   ;; Bitwise AND of current value ...
                                   (aref b u)

                                   ;; ... with o: position U is not a
                                   ;; safe place for W (inverse of O)
                                   ;; anymore, because if we put a W
                                   ;; there, it would attack our
                                   ;; current cell (H,V).
                                   o

                                   ;; ... and with zero (unsafe for
                                   ;; all) if our piece W is also a
                                   ;; knight (resp. queen). Indeed, we
                                   ;; cannot put anything at position
                                   ;; U because we are attacking it.
                                   (if (= w o) 3 0)))))

                  ;; Propagate queens' constraints
                  (dotimes (y N)
                    (dotimes (x N)
                      (let ((u(+(* y n)x))(o 6))
                        (if (or (= x h)
                                (= y v)
                                (= (abs(- h x)) (abs(- v y))))

                            ;; Same code as above #1=(if ...)
                            #1#))))

                  (setf
                   ;; Place piece
                   (aref b u) w

                   ;; Set result value
                   r (or (cond
                           ;; Queen? Try to place a Knight and maybe
                           ;; other queens. The result is true only if
                           ;; the recursive call is.
                           ((= w 5) (R 6 @ U b !))

                           ;; Not a queen, so all below concern   
                           ;; knights: we always return T because
                           ;; we found a safe position.
                           ;; But we still need to know if
                           ;; board B is an actual solution and 
                           ;; call FN if it is.
                           ;; ------------------------------------

                           ;; Can be place a queen too? then current
                           ;; board is not a solution.
                           ((R 5 @ U b()) t)

                           ;; Try to place a queen and a knight
                           ;; without constraining the min positions
                           ;; (% and @); this is the "check" mode that
                           ;; is represented by the last argument to
                           ;; R, set to T here. If it throws true,
                           ;; then board B is a duplicate of a
                           ;; previous one, except that it is missing
                           ;; pieces due to constraints % and @. The
                           ;; "check" mode is a fix to a bug where we
                           ;; reported as solutions boards where there
                           ;; was still room for other pieces.
                           ((catch'!(R 5 0 0 b t)) t)

                           ;; Default case: we could not add one more
                           ;; layer of pieces, and so current board B
                           ;; is a solution. Call function FN.
                           (t (funcall fn b) t))

                         ;; R keeps being true if it already was for
                         ;; another position.
                         r)))))

         ;; Return result R
         r))

    ;; Start search with a queen and an empty board.
    (R 5 0 0 (fill (make-array s) 3)  nil)))

Duplicati e bug

La mia prima soluzione ha prodotto soluzioni duplicate. Per risolverlo, ho introdotto due contatori per regine e cavalieri. Il contatore per le regine (resp. Cavalieri) tiene traccia della prima posizione nel tabellone in cui esiste una regina (resp. Cavaliere): aggiungo una regina (resp. Un cavaliere) solo nelle posizioni che seguono quella posizione minima.

Questi metodi mi impediscono di rivisitare le soluzioni che erano già state trovate nelle precedenti iterazioni, perché ho iterato con una posizione crescente di regina (o cavaliere).

Tuttavia, Sleafar notò che c'erano soluzioni per le quali ci poteva essere spazio per regine e cavalieri, il che è contrario alle regole. Per un po 'ho pensato di tornare a una normale ricerca e memorizzare tutte le soluzioni conosciute per evitare duplicati, che erano troppo costosi (sia in termini di byte che di utilizzo della memoria).

Invece, ecco cosa faccio ora: quando viene trovata una scheda di soluzione potenziale, provo ad aggiungere esattamente una regina e una cavaliere, senza prendere in considerazione i contatori (cioè per tutte le celle sulla scheda). Se ciò è possibile, la scheda corrente è un duplicato di una precedente e rifiuto la soluzione.

test

|---+---------+------------+--------------|
| N |  boards |    seconds |        bytes |
|---+---------+------------+--------------|
| 3 |       0 |          0 |        32768 |
| 4 |      40 |          0 |       360416 |
| 5 |     172 |          0 |      3440016 |
| 6 |    2836 |   0.085907 |     61251584 |
| 7 |   23876 |   1.265178 |    869666288 |
| 8 |  383586 |  24.991300 |  17235142848 |
| 9 | 6064506 | 524.982987 | 359952648832 |
|---+---------+------------+--------------|

Quine-ification

Ho avuto idee diverse per fare quine successive. La più semplice è probabilmente quella di generare prima tutte le soluzioni come un elenco di stringhe e scrivere quines sequenziali che compaiono da tale elenco ad ogni generazione. Tuttavia, questo non sembra essere più breve dell'attuale approccio. In alternativa, ho provato a riscrivere il codice ricorsivo con uno stack personalizzato e scaricare tutte le variabili di stato ogni volta che trovo una soluzione; l'obiettivo è che il passaggio successivo possa essere elaborato come continuazione del passaggio corrente. Forse questo sarebbe più adatto per un linguaggio basato su stack. Quello attuale è abbastanza semplice e si affida alle variabili comuni del lettore Lisp, che sono sempre divertenti da usare.

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.