Segna una partita a Boggle


21

sfondo

In Boggle , un round viene segnato sommando i punti per ogni parola unica trovata da un giocatore (vale a dire qualsiasi parola trovata da più di un giocatore vale 0 punti). I punti vengono calcolati in base al numero di lettere in ciascuna parola, come segue:

3 lettere: 1 punto

4 lettere: 1 punto

5 lettere: 2 punti

6 lettere: 3 punti

7 lettere: 5 punti

8 o più lettere: 11 punti

Sfida

In questa sfida, scrivi un programma o una funzione che includa un elenco di elenchi di stringhe che rappresentano le parole di ciascun giocatore e produca un elenco dei punteggi dei giocatori. Puoi presumere che ci saranno almeno 2 giocatori e tutte le parole saranno 3 o più lettere e saranno tutte minuscole (o tutte maiuscole se preferisci). Puoi anche presumere che ogni giocatore userà ogni parola una sola volta; cioè, nessun elenco di giocatori conterrà duplicati. Questo è il golf del codice, quindi vince la risposta più breve in byte.

Regole

L'input può essere preso in qualsiasi formato ragionevole. Gli esempi includono un elenco di elenchi di stringhe, un elenco di stringhe separate da virgola, una stringa separata da virgola su ogni riga di input, ecc. L'output può essere sotto forma di un elenco di numeri interi (o equivalente della tua lingua) oppure puoi stampare i valori da stdout usando un separatore di tua scelta (come una nuova riga).

Casi test

Input => Output

[["cat","dog","bird","elephant"],
 ["bird","dog","coyote"],
 ["dog","mouse"]]                 => [12,3,2]

[["abc","def","ghi"],
 ["ghi","def","abc"]]             => [0,0]

[["programming","puzzles"],
 ["code","golf"],
 []]                              => [16,2,0]

Risposte:


6

Husk , 21 20 19 byte

-2 byte grazie a Zgarb

Idea tratta da A055228

ṠṀöṁ(⌈√Π-3▼8L)fε`#Σ

Provalo online!

Spiegazione (della versione precedente)

            ṠṀ-oṠ-uΣ   Remove duplicated words
                   Σ   Concatenate
                  u    Remove duplicates
               oṠ-     Remove those unique elements from the list (give list of elements that appear more than once)
            ṠṀ-        Remove those words from each list in the input
m                      For each list
 ṁ(                    Map then sum
          L)           Length
        ▼8             Min(8,x)
      -3               Minus 3
     Π                 Factorial
    √                  Square root
   ⌈                   Ceiling


Bene, non riorganizzerò però, per risparmiare sulla spiegazione.
H.Piz,

19 byte usandof invece di-
Zgarb

Grazie, non sono riuscito a far funzionare quel metodo da solo.
H.Piz,

Gah! Pensavo di essere riuscito a legarti, non avevo notato che ora hai meno di 19 anni.
Shaggy,

3

R , 142 126 121 117 byte

function(L)sapply(lapply(L,setdiff,(l=unlist(L))[duplicated(l)]),function(x)sum(c(1,1,2,3,5,11)[pmin(6,nchar(x)-2)]))

Provalo online!

Prende Lcome un elenco di vettori di stringhe; restituisce i valori.

Innanzitutto, sono unlistle parole, trovano i duplicati, quindi li rimuovono dagli elenchi di parole dei giocatori. Quindi prende queste liste di parole uniche e calcola i punteggi di ciascuna, usando pminper assicurarsi che le parole più lunghe di 8 vengano segnate come 11.


È possibile accorciarlo a 108 byte se si eliminano solo i duplicati nella funzione interiore sapply:function(L)sapply(L,function(x)sum(c(1,1,2,3,5,11)[pmin(6,nchar(x[!x%in%(l=unlist(L))[duplicated(l)]])-2)]))
plannapus,

3

JavaScript (ES6), 92 byte

a=>a.map(b=>b.reduce((s,v)=>s+(a.filter(b=>b.includes(v))[1]?0:+"11235"[v.length-3]||11),0))

Un po 'simile alla risposta di Rick Hitchcock ma creato principalmente in modo indipendente; Ho usato un metodo diverso di summing ( reduce) e un metodo diverso per verificare i termini ripetuti (filter + includes). Ringraziatelo per l'idea di controllare l'oggetto [1]invece di controllare .length>1, però.

Casi test


Dovresti essere in grado di salvare un byte usando s+=e rimuovendo le parentesi attorno ai ternari. E altri 3 usando mapinvece di reduce: tio.run/##NY/…
Shaggy

Molto bene. Il tuo uso reducee includesrende la tua risposta molto diversa dalla mia.
Rick Hitchcock,

3

JavaScript (ES6), 106 93 byte

[Salvato 13 (!) Byte, grazie ad Arnauld, Shaggy e JollyJoker.]

a=>a.map(b=>b.map(c=>x+=(a+'').split`,`.filter(d=>d==c)[1]?0:+'11235'[c.length-3]||11,x=0)|x)

Casi test:


2
Penso che puoi sostituirlo c[7]?11:c[6]?5:c[5]?3:c[4]?2:1con '00011234'[c.length]||11.
Arnauld,

Questo dà [15,2,0]invece che [16,2,0]per l'ultimo caso di test, ma probabilmente è stato risolto facilmente. Funzionerà un po 'di più dopo cena, a meno che non pubblichi una risposta geniale (come al solito). Grazie! :)
Rick Hitchcock

1
Ah sì, scusa, dovrebbe essere '00011235'.
Arnauld,

1
Penso che puoi salvare altri pochi byte in aggiunta al suggerimento di @ Arnauld in questo modo .
Shaggy,

1
Ci sono almeno 3 lettere '11235'[c.length-3]||11, giusto?
JollyJoker,


2

Pyth , 26 byte

Usa la formula di H.PWiz .

m+Fm.E@.!a3hS,8lk2fq1/sQTd

Verifica tutti i casi di test.

La versione iniziale, 33 byte :

m+Fm*h+++*6>lk7y>lk6>lk5glk3q1/sQ

Verifica tutti i casi di test.

Spiegazione

m + Fm * h +++ * 6> lk7y> lk6> lk5> glk3q1 / sQ Programma completo.

m Mappa sopra l'ingresso.
   m Mappa su ciascun elenco secondario.
                        > lk3 La lunghezza è superiore a 2? 1 se vero e 0 se falso.
      +> lk5 Plus "è maggiore di 5?".
       + y> lk6 Plus "è una lunghezza superiore a 6?", raddoppiata.
        + * 6> lk7 Plus "è maggiore di 7?", Volte 6.
     h Incremento.
                            q1 / sQ Conta le occorrenze dell'elemento nell'appiattito
                                     input e controlla se è uguale a 1. 0 se False, 1 se True.
    * Moltiplicazione.
 + F Somma ogni elenco secondario.


2

Japt , 29 25 24 23 21 20 byte

Ëx@èøX ¥1©3nXÊm8)ʬc

Provalo


Spiegazione

Input implicito di array U.

Ëx@

Mappare sull'array ( Ë) e ridurre ciascun array secondario mediante addizione ( x) dopo aver passato i suoi elementi attraverso la seguente funzione, dove si Xtrova la parola corrente.

èøX

Count ( è) gli elementi Uche contengono ( ø) X.

¥1

Controlla se è uguale a 1.

©

AND logico ( &&).

3nXÊm8)

Sottrai ( n) 3 dal minimo di ( m) 8 e dalla lunghezza ( Ê) di X.

ʬc

Fattoriale, radice quadrata e arrotondamento, rispettivamente.




1

Java 8, 202 200 198 byte

a->{int q=a.length,r[]=new int[q],i=0,j,f;for(;i<q;i++)for(String s:a[i]){for(f=j=0;j<q;)f|=a[j].contains(s)&!a[i].equals(a[j++])?1:0;if(f<1)r[i]+=(j=s.length())<5?1:j<6?2:j<7?3:j<8?5:11;}return r;}

OPPURE (anche 198 byte )

a->{int q=a.length,r[]=new int[q],i=0,j,f=1,e=0;for(;i<q;r[i++]+=f<1?e<5?1:e<6?2:e<7?3:e<8?5:11:0)for(String s:a[i])for(f=j=0;j<q;e=s.length())f|=a[j].contains(s)&!a[i].equals(a[j++])?1:0;return r;}

Può sicuramente essere giocato a golf .. Purtroppo Java non ha build-in o metodi brevi per rimuovere tutti gli elementi di tutti gli elenchi presenti in più ..

Spiegazione:

Provalo qui.

a->{                       // Method with ArrayList<String>[] parameter & int[] return-type
  int q=a.length,          //  Length of the input-array
      r[]=new int[q],      //  Result integer-array the size of the input-array
      i=0,j,               //  Index integers
      f;                   //  Flag integer (used as boolean)
  for(;i<q;i++)            //  Loop (1) over the input array
    for(String s:a[i]){    //   Inner loop (2) over the Strings of the current List
      for(j=f=0;           //    Reset the flag `f` and index `j` both to 0
                j<q;)      //    Inner loop (3) over the input list again
        f|=a[j].contains(s)//     If the current list (3) contains the current String (2)
           &!a[i].equals(a[j++])?
                           //     and the current list (3) is not the current list (1)
            1              //      Bitwise-OR the flag with 1 (0->1; 1->1)
           :               //     Else:
            0;             //      Bitwise-OR the flag with 0 (0->0; 1->1)
                           //    End of inner loop (3) (implicit / single-line body)
      if(f<1)              //    If the flag is still 0 (so the current String is unique)
        r[i]+=             //     Increase the current item in the result integer-array by:
              (j=s.length())<5?
                           //      If the length is below 5:
               1           //       By 1
              :j<6?        //      Else-if the length is below 6:
               2           //       By 2
              :j<7?        //      Else-if the length is below 7:
               3           //       By 3
              :j<8?        //      Else-if the length is below 8:
               5           //       By 5
              :            //      Else (above 7):
               11;         //       By 11
    }                      //   End of inner loop (2)
                           //  End of loop (1) (implicit / single-line body)
  return r;                //  Return the resulting integer-array
}                          // End of method

Adoro i ternari e l'unica cosa che odio di ScaLa è che hanno rimosso questa sintassi ternaria.
V. Courtois,

@ V.Courtois Hmm, per curiosità, com'è adesso la sintassi ternaria in Scala?
Kevin Cruijssen,

uh: if (bool1) exp1 else exp2
V. Courtois,

1

R, 117 byte

Un approccio completamente diverso dall'altra risposta R :

function(L)sapply(L,function(x)sum(c(0:3,5,11)[cut(nchar(x[x%in%names(which(table(unlist(L))<2))]),c(0,2,4:7,Inf))]))

Casi test:

> f=function(L)sapply(L,function(x)sum(c(0:3,5,11)[cut(nchar(x[x%in%names(which(table(unlist(L))<2))]),c(0,2,4:7,Inf))]))
> L=list(c("cat","dog","bird","elephant"),c("bird","dog","coyote"),c("dog","mouse"))
> f(L)
[1] 12  3  2
> L=list(c("abc","def","ghi"),c("ghi","def","abc"))
> f(L)
[1] 0 0
> L=list(c("programming","puzzles"),c("code","golf"),c())
> f(L)
[1] 16  2  0

Prende i nomi che ricorrono solo una volta nell'elenco, converte la loro lunghezza in un fattore basato sui punti di cut-off dati e li traduce in punteggi che vengono quindi sommati.


114 byte combinando i nostri due approcci nella fase di deduplicazione.
Giuseppe,

0

Perl 5 , 104 + 2 (-na) = 106 byte

push@a,[@F];map$k{$_}++,@F}{map{$s=0;map$s+=(($l=y///c)<8?$l<7?$l<5?1:$l-3:5:11)*($k{$_}<2),@$_;say$s}@a

Provalo online!


0

Clojure, 102 byte

#(for[p %](apply +(for[w p](if(next(filter #{w}(flatten %)))0(get{3 1 4 1 5 2 6 3 7 5}(count w)11)))))

nextritorna nilse c'è solo una parola w:)


0

PHP , 226 byte

function x($a){foreach($a as$p){$q=call_user_func_array('array_diff',$a);array_push($a,array_shift($a));$x=0;array_map(function($b)use(&$x){$b=strlen($b);$x+=($b<5?1:($b==5?2:($b==6?3:($b==7?5:11))));},$q);$o[]=$x;}return $o;}

Penso che questo potrebbe ancora essere ridotto un po '.

Ungolfed:

function x($a) {
    foreach ($a as $p) {
        $q = call_user_func_array('array_diff', $a);
        array_push($a, array_shift($a));
        $x = 0;
        array_map(function($b) use (&$x){
            $b = strlen($b);
            $x += ($b < 5 ? 1 : ($b == 5 ? 2 : ($b == 6 ? 3 : ($b == 7 ? 5 : 11))));
        }, $q);
        $o[] = $x;
    }
    return $o;
}

Provalo online!


0

Scala , 242 byte

La funzione accetta, come parametro a, a Seq[Set[String]]e restituisce un Array[Int]. Uso un array per renderlo mutabile (perdita di 4 caratteri).

var s=Seq("")
a.foreach(x=>x.foreach(y=>s:+=y))
var u:Array[Int]=Array()
var i= -1
a.foreach(t=>{i+=1
u:+=0
t.map(x=>{val l=x.length
if(s.count(_==x)<2){if(l>7)u(i)+=11
if(l==7)u(i)+=5
if(l==6)u(i)+=3
if(l==5)u(i)+=2
if(l>2&l<5)u(i)+=1}})})
u

Provalo online!

Potrebbe essere ottimizzabile, dal momento che non ho nemmeno lavorato sul

if(l>7)u(i)+=11
if(l==7)u(i)+=5
if(l==6)u(i)+=3
if(l==5)u(i)+=2
if(l>2&l<5)u(i)+=1

parte. Grazie per questa sfida!


0

Swift 4 , 164 byte *

{$0.map{Set($0).subtracting(Dictionary(grouping:$0.flatMap{$0},by:{$0}).flatMap{$1.count != 1 ?$0:nil}).map{[0,1,1,2,3,5,11][min(max($0.count-2,0),6)]}.reduce(0,+)}}

L'espressione sopra è tecnicamente corretta, pura Swift. Tuttavia, l'espressione è così complessa che, a causa dell'esplosione esponenziale nel sistema di inferenza del tipo, non può essere elaborata prima che il compilatore si arrenda dopo un timeout arbitrario (come 15 secondi o qualcosa del genere).

Per rendere questa espressione compilabile con il compilatore corrente, può essere suddivisa in questo modo:

{
let n = Dictionary(grouping:$0.flatMap{$0},by:{$0}).flatMap{$1.count != 1 ?$0:nil}
return $0.map{Set($0).subtracting(n).map{[0,1,1,2,3,5,11][min(max($0.count-2,0),6)]}.reduce(0,+)}
}

Casi test:

let f: (_ input: [[String]]) -> [Int] = {
    let n = Dictionary(grouping:$0.flatMap{$0},by:{$0}).flatMap{$1.count != 1 ?$0:nil}
    return $0.map{Set($0).subtracting(n).map{[0,1,1,2,3,5,11][min(max($0.count-2,0),6)]}.reduce(0,+)}
}

let testcases: [(input: [[String]], expected: [Int])] = [
    (input: [
            ["cat","dog","bird","elephant"],
            ["bird","dog","coyote"],
            ["dog","mouse"]
        ],
        expected: [12,3,2]
    ),
    (input: [
            ["abc","def","ghi"],
            ["ghi","def","abc"]
        ],
        expected: [0,0]
    ),
    (input: [
            ["programming","puzzles"],
            ["code","golf"],
            []
        ],
        expected: [16,2,0]
    ),
]

for (caseNumber, testcase) in testcases.enumerated() {
    let actual = f(testcase.input)
    assert(actual == testcase.expected,
        "Testcase #\(caseNumber) \(testcase.input) failed. Got \(actual), but expected \(testcase.expected)!")
    print("Testcase #\(caseNumber) passed!")
}

Suddiviso:

let verboseF: (_ input: [[String]]) -> [Int] = { playerHands in
    let allWords = playerHands.flatMap{$0}
    // demo data for first test case:
    // allWords: ["cat", "dog", "bird", "elephant", "bird", "dog", "coyote" "dog", "mouse"]

    let allWordsGroupedByThemselves = Dictionary(grouping: allWords, by: {$0})
    /* allWordsGroupedByThemselves:
    [
        "cat": ["cat"],
        "dog": ["dog", "dog", "dog"],
        "bird": ["bird", "bird"],
        "elephant": ["elephant"],
        "coyote": ["coyote"], "mouse": ["mouse"]
    ]*/

    let allWordsUsedMoreThanOnce = allWordsGroupedByThemselves.flatMap{$1.count != 1 ?$0:nil}
    // allWordsUsedMoreThanOnce: ["dog", "bird"]

    return playerHands.map{ hand in
        // demo data for first hand of first test case:
        // hand: ["cat","dog","bird","elephant"]

        let uniqueWordsInHand = Set(hand)
        // uniqueWordsInHand: ["cat","dog","bird","elephant"]

        let uniqueWordsInHandNotUsedByOthers = uniqueWordsInHand.subtracting(allWordsUsedMoreThanOnce)
        // uniqueWordsInHandNotUsedByOthers: ["cat", "elephant"]

        let wordLengths = uniqueWordsInHandNotUsedByOthers.map{$0.count}
        // wordLengths: [3, 8]

        let scores = wordLengths.map{ wordLength in
            return [0,1,1,2,3,5,11][min(max(wordLength-2, 0), 6)] //A look up table that maps word length to word score
        }
        //scores: [1, 11]

        let playerScore = scores.reduce(0,+)
        // playerScore: 12

        return playerScore
    }
}

0

ASP + Python , 137 byte

u(P,W):-1{p(_,W)}1;p(P,W).s(P,S):-S=#sum{@v(W):u(P,W)};p(P,_).#script(python)
def v(w):return[1,1,2,3,5,11][min(len(w.string),8)-3]#end.

Si aspetta che i dati siano formattati come:

p(1,("cat";"dog";"bird";"elephant")).
p(2,("bird";"dog";"coyote")).
p(3,("dog";"mouse")).

Richiede clingo 5.2.1 con supporto per Python.

Ungolfed:

unique(P,W):- 1 { player(_,W) } 1 ; player(P,W).
score(P,S):- S = #sum{@value(W): unique(P,W)} ; player(P,_).
#script (python)
def value(word):
    return [1,1,2,3,5,11][min(len(word.string),8)-3]
#end.

La funzione Python è fortemente ispirata dalla risposta Python .

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.