Generatore di sequenze Karel J. AlphaBot


14

I punteggi

Questa sezione verrà compilata man mano che vengono inserite le domande.

Normale

1. bopjesvla    Perl                54
2. edc65        Javascript (ES6)    91
3. name         language            score
4. name         language            score
5. name         language            score

Round bonus

1. name   language   score
2. name   language   score
3. name   language   score
4. name   language   score
5. name   language   score

Karel J. AlphaBot

sfondo

Un popolare corso introduttivo a Java è Karel J. Robot (lo sto usando da solo). Il robot interagisce con una griglia di strade (coordinate y positive intere) e viali (coordinate x positive positive) nonché con i segnali acustici, che possono essere posizionati e memorizzati sulla griglia (notare che Karel e tutti i segnali acustici possono esistere solo su un reticolo punti). Karel (il robot) deve solo eseguire cinque azioni: andare avanti di 1, girare a sinistra in posizione, abbassare un segnale acustico, raccogliere un segnale acustico e spegnersi.

Nella mia lezione di Informatica, uno dei nostri primi compiti è stato programmare Karel per imparare a girare a destra, a girare intorno e ad eseguire l'azione combinata di andare avanti di 1 e di emettere un segnale acustico. Un compito qualche giorno dopo era di usare questi metodi e scrivere nuovi metodi per produrre lettere dell'alfabeto.

Naturalmente, una volta terminato questo incarico, ho scritto più metodi per realizzare ogni lettera dell'alfabeto, nonché le dieci cifre numeriche, e ho intenzione di capire come realizzare una sorta di word processor dal robot, dove una stringa verrebbe inserito in STDIN e il robot inserirà i segnali acustici sulla griglia in modo simile alle lettere.

Ogni volta che ho scritto private void draw#per ogni personaggio #, ho aggiunto un commento dopo di esso che mi avrebbe detto abbreviazioni per la sequenza di comandi di cui avrei bisogno.

Ho a disposizione i seguenti comandi (scritti in pseudocodice) (chiarimento: questi sono gli unici comandi utili ).

Turn Left
    Rotate the robot 90˚ counterclockwise
    Abbreviated as "l"

Turn Right
    Rotate the robot 90˚ clockwise
    Abbreviated as "r"

Move
    Move one space forwards
    Abbreviated as "m"

Put Beeper
    Put a beeper on the spot that Karel is on
    Abbreviated as "p"

Drop Beeper
    Move, then Put Beeper
    Abbreviated as "d"

Turn Around
    Turn Left, then Turn Left
    Abbreviated as "a"

condizioni

Il robot deve procedere nel seguente ordine.

  • Il robot inizia nell'angolo in basso a sinistra del rettangolo 5xN dell'area minima in cui verrà disegnata la lettera.
  • Il robot disegna la lettera.
  • Il robot si sposta nell'angolo in basso a destra del rettangolo.
  • Il robot sposta due spazi a destra e deve essere rivolto a nord / su

Facciamo un esempio. Supponiamo di voler disegnare A. La posizione del robot è la lettera che indica la sua direzione (nord, sud, est, ovest). La lettera è maiuscola se il robot si trova in un punto con un segnale acustico e minuscolo se il robot si trova in un punto senza un segnale acustico. orappresenta i punti con i segnali acustici e .rappresenta i punti senza i segnali acustici.

Come vedremo più avanti, Aè questo.

.ooo.
o...o
ooooo
o...o
o...o

Ecco una possibile soluzione.

Grids   .....   .....   .....   .....   .....   .....   .....   .....   .....
        .....   .....   .....   .....   .....   .....   .....   .....   .....
        .....   .....   .....   N....   E....   oE...   ooE..   oooE.   oooW.
        .....   .....   N....   o....   o....   o....   o....   o....   o....
        n....   N....   o....   o....   o....   o....   o....   o....   o....

Letters           p       d       d       r       d       d       d       a

        .....   .....   .....   .....   .....   n....   e....   .E...   .oE..
        .....   .....   .....   .....   N....   o....   o....   o....   o....
        ooWo.   oWoo.   Wooo.   Nooo.   oooo.   oooo.   oooo.   oooo.   oooo.
        o....   o....   o....   o....   o....   o....   o....   o....   o....
        o....   o....   o....   o....   o....   o....   o....   o....   o....

          m       m       m       r       d       m       r       d       d

        .ooE.   .oooe   .ooos   .ooo.   .ooo.   .ooo.   .ooo.   .ooo.
        o....   o....   o....   o...S   o...o   o...o   o...o   o...o
        oooo.   oooo.   oooo.   oooo.   ooooS   ooooo   ooooo   ooooo
        o....   o....   o....   o....   o....   o...S   o...o   o...o
        o....   o....   o....   o....   o....   o....   o...S   o...E

          d       m       r       d       d       d       d       l

Il finale mmlper completare il quarto punto è implicito perché appare in ogni lettera e perché non voglio tornare indietro e aggiungere altre due colonne a tutto nella soluzione sopra proposta.

Pertanto, una soluzione da fare Aè pddrdddammmrdmrdddmrddddlmml.

Nota che questa non deve essere la tua soluzione. Il tuo algoritmo può passare attraverso ogni colonna, posizionando i segnali acustici nei posti giusti e senza fare affidamento su dove sono stati posizionati o verranno posizionati altri segnali acustici. Indipendentemente dal tuo algoritmo, il robot può posizionare solo un segnale acustico per spazio sulla griglia.


Il programma

Il tuo programma prenderà come input una griglia 5xN di ciò che è la griglia per la lettera. Si noti che non è presente alcun robot sull'ingresso; si presume che il robot sia nell'angolo in basso a sinistra (sud-ovest), esposto a nord.

L'output sarà la sequenza di lettere che è la scorciatoia per la sequenza.

Ingressi campione

.ooo.
o...o
ooooo
o...o
o...o

o...o.ooooo
o...o...o..
ooooo...o..
o...o...o..
o...o.ooooo

Output di esempio

pddrdddammmrdmrdddmrddddlmml

prmmmlmlmmdrdrdddlmlmmdrdrmmmdrddddlmmlprdddlmldmmrmrmdmlmldmmrdrddddrmmmdlmml

Questo è il codice golf, ragazzi. Si applicano le regole CG standard. Vince il codice più breve in byte.


Round bonus

Regole

Se vuoi partecipare al round bonus, assicurati di rendere i tuoi codici efficienti! Di seguito è una libreria di tutte le lettere 5x5 che il mio programma crea quando viene eseguito. L'obiettivo del round bonus è scrivere un programma che stampi una sequenza ABCDEFGHIJKLMNOPQRSTUVWXYZche contenga il minor numero di mosse possibile. Non c'è input per STDIN. Il codice verrà valutato non in base alla lunghezza del codice ma al suo "punteggio di movimento". Il punteggio di spostamento è progettato per scoraggiare gli algoritmi di sweeper che visitano ogni punto del rettangolo.

d: 1
l: 1
m: 4
p: 1
r: 1

Lettere

.ooo.   oooo.   ooooo   oooo.   ooooo   ooooo   .oooo   o...o
o...o   o...o   o....   o...o   o....   o....   o....   o...o
ooooo   oooo.   o....   o...o   oooo    oooo.   o.ooo   ooooo
o...o   o...o   o....   o...o   o....   o....   o...o   o...o
o...o   oooo.   ooooo   oooo.   ooooo   o....   oooo.   o...o

ooooo   ....o   o...o   o....   ooooo   o...o   ooooo   oooo.
..o..   ....o   o..o.   o....   o.o.o   oo..o   o...o   o...o
..o..   ....o   oo...   o....   o.o.o   o.o.o   o...o   oooo.
..o..   o...o   o..o.   o....   o...o   o..oo   o...o   o....
ooooo   .ooo.   o...o   ooooo   o...o   o...o   ooooo   o....

oooo.   oooo.   ooooo   ooooo   o...o   o...o   o...o   o...o
o..o.   o...o   o....   ..o..   o...o   o...o   o...o   .o.o.
o..o.   oooo.   ooooo   ..o..   o...o   .o.o.   o.o.o   ..o..
oooo.   o..o.   ....o   ..o..   o...o   .o.o.   o.o.o   .o.o.
....o   o...o   ooooo   ..o..   ooooo   ..o..   ooooo   o...o

o...o   ooooo
.o.o.   ...o.
..o..   ..o..
.o...   .o...
o....   ooooo

È necessario seguire la stessa procedura della sfida originale: le lettere devono essere disegnate una alla volta con una separazione di spazio tra ogni lettera.

Si applicano le regole CG standard. Vince l'ingresso con il punteggio di mossa più basso.




Per riassumere, entrambi i codici faranno essenzialmente le stesse cose. Il primo codice dovrebbe avere un numero minimo di byte nel codice e il secondo codice dovrebbe usare il minor numero di mosse.


Sfida ordinata - non ho idea del motivo per cui ti stai sottovalutando.
Deusovi,

1
Grazie @Deusovi. Vorrei che spiegassero perché così posso chiarire tutto ciò che non ha senso o migliorarlo.
Arturo,

" Karel (il robot) è solo per eseguire cinque azioni ": penso che ti manchi " capace ", e sicuramente ti manca la quinta azione. E non sono sicuro di cosa significhi il bonus round: assegnerai un premio alla persona che scrive la soluzione migliore?
Peter Taylor,

Forse invece di una sfida di golf di codice cambiarlo in una sfida di golf mossa minima? Dal momento che si tratta di efficienza.
LukStorms,

1
Una sfida di mosse minime con un numero limitato di mosse non è così interessante senza la parte del golf del codice. Dovrebbe essere abbastanza facile BFS il percorso ottimale.
bopjesvla,

Risposte:


5

perl -p0, 60 56 54 + 2 byte

golf

/
/;$:="m"x"@-";$_=mmmmlma.s/
/rmr$:a/gr.mml;y/.o/md/;

Appunti

/\n/; # capture the length of the first line
$:="m"x"@-"; # assign a string of m's with that length to $:
s/^/mmmmlmll/; # move to the starting position (-1,0)
s/\n/rmr$:rr/g; # replace all newlines with kareliage returns
y/.o/md/; # replace dots with moves and o's with drops
s/$/mml/; # append mml

Un buon uso di @-, potrebbe essere utile da condividere sui suggerimenti per giocare a golf nella domanda Perl !
Dom Hastings,

2

JavaScript (ES6), 91

Un primo tentativo per la sfida di base.

Prova a eseguire lo snippet di seguito in un browser compatibile con EcmaScript 6 (testato in Firefox)

RISPOSTA SFIDA BONUS - Punteggio per alfabeto completo = 869

Prova a eseguire il wnippet di seguito in Firefox (meglio schermo intero)

Poiché non mi piacciono le sfide di input / output fissi , puoi provare il tuo input. Ricorda, verranno stampate solo le lettere.

// Optimal - working on small pattern but too slow (scale bad)
// So I build the total command letter by letter - that surely is NOT globally optimal

Key=sol=>sol.pos+' '+sol.setBits

Solve=(target, startRow, startDir, cmd)=>{
  // Target is a rectangle string 5x5, newline separated for total (5+1)*5 chars
  if (target[target.length-1] != '\n') target += '\n';
  
  var T = ~new Date()
  var width = 5, height = 5, startPos = (width+1)*startRow;
  var offset = [-width-1, 1, width+1, -1];
  var turns = [ "", "r", "rr", "l" ];
  var cmds = [ "m", "rm", "rrm", "lm", "d", "rd", "rrd", "ld" ];
  var visited = {}, scan =[[],[],[],[],[],[],[],[]], cscan;
  
  var baseSol = { steps:[], pos: startPos, dir: startDir, setBits: 0};
  var score = 0, j = 0
  var bit, key, turn, curSol, move, result
  var targetBits = 0; 
  [...target].map((c,i)=>targetBits |= ((c=='o')<<i)) // 30 bits
  
  // First step, from outside, set bit in mask if it's set in target
  if (target[startPos]=='o') baseSol.setBits = 1<<startPos;
  console.log(target, targetBits.toString(16))
  visited[Key(baseSol)] = scan[0].push(baseSol);
  

  for (j = 0; j<99; j++)
  {
     cscan = scan[j];
     scan.push([])
     
     // console.log(`T: ${T-~new Date} J: ${j} SC: ${cscan.length}`)
     while (cscan.length > 0)
     {
        baseSol = cscan.pop()
        //console.log('Base', baseSol.dir, baseSol.pos, baseSol.setBits.toString(16), baseSol.steps.length)
        for(turn = 0; turn < 4; turn++)
        {
           // set direction, move and drop if you can
           curSol = {};
           curSol.dir = baseSol.dir + turn & 3;
           curSol.pos = baseSol.pos + offset[curSol.dir];
           // console.log(turn, curSol.dir, curSol.pos)
           if(target[curSol.pos] > ' '
              || curSol.dir == 1 && target[curSol.pos]=='\n'
             ) // if inside grid or on right border facing east
           {
              score = j + (turn == 2 ? 3 : turn == 0 ? 1 : 2);
              bit = 1 << curSol.pos;
              if (targetBits & bit)
                 curSol.setBits = baseSol.setBits | bit, move = 4 | turn;
              else
                 curSol.setBits = baseSol.setBits, score += 3, move = turn;
              if (!visited[key = Key(curSol)]) 
              {
                 curSol.steps = [...baseSol.steps, move] // clone and add
                 // task completed if on  right border and all bits ok
                 if (target[curSol.pos]>' ')
                 { // not on right border, proceed  
                    visited[key] = scan[score].push(curSol)
                 }  
                 else if (curSol.setBits == targetBits)
                 {
                    result = curSol.steps.map(v=>cmds[v]).join``
                    result = (cmd == '' 
                    ? target[startPos]=='o' ? 'p' : '' 
                    : target[startPos]=='o' ? 'd' : 'm') + result;
                    console.log(`T: ${T-~new Date} J: ${j} CMD: ${result}`)
                    return [cmd+result, curSol.pos / (width+1) | 0];
                 }
              }
           }
        }
     }
  }
  // Miserable failure!
  return []
}  

console.log=(...x)=>LOG.innerHTML+=x+'\n';
// TEST
Karel=(cmd, width, height) =>  // even if for this test we have a limited height to handle
{ 
  var grid = [...('.'.repeat(width)+'\n').repeat(height)],
  o = width+1,p = o*(height-2)+1,d = [-o, 1, o, -1], // direction offsets
  steps = [],s = [...grid],q = 0; // face up

  s[p] = 'n';
  steps.push([s.join``,'-']);
  
  [...cmd].forEach(c => 
    (
      c == 'l' ? q = q-1 &3
      : c == 'r' ? q = q+1 &3
      : c == 'a' ? q = q+2 &3
      : c == 'm' ? p += d[q]
      : c == 'p' ? grid[p] = 'o'
      : c == 'd' ? grid[p += d[q]] = 'o'
      : 0,
      s = [...grid],  
      s[p] = s[p] == 'o' ? 'NESW'[q] : 'nesw'[q],
      steps.push([s.join``,c])
    )
  )
  return [s.join``,steps]
}  


var AlphabetMap = `.ooo..oooo..ooooo.oooo..ooooo.ooooo..oooo.o...o.ooooo.....o.o...o.o.....ooooo.o...o.ooooo.oooo..oooo..oooo..ooooo.ooooo.o...o.o...o.o...o.o...o.o...o.ooooo
o...o.o...o.o.....o...o.o.....o.....o.....o...o...o.......o.o..o..o.....o.o.o.oo..o.o...o.o...o.o..o..o...o.o.......o...o...o.o...o.o...o..o.o...o.o.....o.
ooooo.oooo..o.....o...o.oooo..oooo..o.ooo.ooooo...o.......o.oo....o.....o.o.o.o.o.o.o...o.oooo..o..o..oooo..ooooo...o...o...o..o.o..o.o.o...o.....o.....o..
o...o.o...o.o.....o...o.o.....o.....o...o.o...o...o...o...o.o..o..o.....o...o.o..oo.o...o.o.....oooo..o..o......o...o...o...o..o.o..o.o.o..o.o...o.....o...
o...o.oooo..ooooo.oooo..ooooo.o.....oooo..o...o.ooooo..ooo..o...o.ooooo.o...o.o...o.ooooo.o.........o.o...o.ooooo...o...ooooo...o...ooooo.o...o.o.....ooooo`.split('\n')
var LetterMap = [];
var l,row,m;

for (l=0;l<26;l++)
{
  for(m='',row=0;row<5;row++)
    m += AlphabetMap[row].substr(l*6,5)+'\n'
  LetterMap[l]=m;  
}

print=Message=>{
  var Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  var startRow = 4, cmd=''
  var startDir = 0 // start facing UP
  ;[...Message].forEach(l => (
    [cmd, startRow] = Solve(LetterMap[Alphabet.search(l)], startRow, startDir, cmd),
    startDir = 1, // after each letter will be facing RIGHT
    cmd += '\n' // addin a newline (scoring 0) just for readability
  ))

  if (startRow != 4) 
    cmd += 'mr'+'m'.repeat(4-startRow)+'rr' // on last row and facing up
  else 
    cmd += 'ml' // ...facing up

  // Recalc score
  var score = 0
  ;[...cmd].forEach(c=>score += c=='m'? 4 : c<' '? 0: 1)

  var robot = Karel(cmd.replace(/\n/g,''), 26*7, 7)
  O.innerHTML=cmd+'\nScore:'+score
  R.innerHTML=robot[0]
  RS.innerHTML=robot[1].join`\n`
}  

function test()
{
  var msg = I.value.toUpperCase()
  msg=msg.replace(/[^A-Z]/g,'')
  I.value=msg
  print(I.value)
}

test()
fieldset {
  padding:0;
}

pre {
  margin: 2px;
}

#RS {
  height: 200px;
  width: 50%;
  overflow:auto;
}

#I { width: 50% }
<fieldset ><legend>Message to print</legend>
<input id=I value='ABCDEFGHIJKLMNOPQRSTUVWXYZ'><button onclick='test()'>go</button></fieldset>
<fieldset ><legend>Command Result (newlines added for readability)</legend>
<pre id=O></pre></fieldset>
<fieldset ><legend>Robot output</legend>
<pre id=R></pre></fieldset>
<fieldset ><legend>Robot step by step</legend>
<pre id=RS></pre></fieldset>
<fieldset ><legend>log</legend>
<pre id=LOG></pre></fieldset>


Come va il bonus?
Arcturus,

@Eridan il bonus sta andando bene. Purtroppo ho anche un lavoro ... :)
edc65,

Ok! Non ti biasimo. Sei l'unico che ha tentato il bonus.
Arcturus,
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.