得分游戏


21

背景

Boggle中,通过将玩家找到的每个唯一单词的得分相加(即,一个以上玩家找到的任何单词的得分为0分),为该回合得分。根据每个单词中字母的数量来计算分数,如下所示:

3个字母:1分

4个字母:1分

5个字母:2分

6个字母:3分

7个字母:5分

8个或更多字母:11分

挑战

在这个挑战中,编写一个程序或函数,该程序或函数接受代表每个玩家单词的字符串列表的列表,并输出玩家分数的列表。您可以假设至少有2位玩家,所有单词均为3个或更多字母,并且全部为小写字母(如果愿意,可以全部为大写字母)。您还可以假设每个玩家只会使用每个单词一次;也就是说,任何玩家的列表都不会包含重复项。这是代码高尔夫球,因此最短答案以字节为单位。

规则

输入可以采用任何合理的格式。示例包括字符串列表,逗号分隔的字符串列表,输入的每一行上的逗号分隔的字符串等。输出可以采用整数列表的形式(或与您的语言相当的形式),也可以打印使用您选择的分隔符(例如换行符)将其输出到stdout的值。

测试用例

输入=>输出

[["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]

Answers:


6

外壳21 20 19字节

-2个字节,感谢Zgarb

取自A055228

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

在线尝试!

说明(旧版本)

            ṠṀ-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


好的,为了节省解释,我不会重新排列。
H.PWiz

使用19个字节f而不是-
Zgarb

谢谢,我无法完全掌握这种方法。
H.PWiz

加!以为我设法绑住了你,没注意到你现在已经不到19岁。
毛茸茸的

3

[R 142个 126 121 117字节

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)]))

在线尝试!

注意到L作为字符串的矢量的列表; 返回值。

首先,unlist是单词,找到重复的单词,然后将其从玩家的单词列表中删除。然后,它使用这些唯一的单词列表并计算每个单词的分数,pmin以确保长于8的单词的得分为11。


如果只删除了内部应用程序中的重复项,则可以将其缩短为108个字节: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个字节

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

有点类似于里克·希区柯克的回答,但大多是独立创建的;我使用了另一种求和(reduce)的方法,以及另一种用于检查重复项的方法(filter + includes)的方法。感谢他检查项目的想法[1]而不是检查.length>1

测试用例


您应该能够通过使用s+=和删除三进制周围的括号来保存一个字节。还有3个,map而不是使用reducetio.run/##NY/…
Shaggy

做得好。您使用reduceincludes使您的答案与我的完全不同。
里克·希区柯克

3

JavaScript(ES6),106 93字节

[节省了13(!)字节,这要感谢Arnauld,Shaggy和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)

测试用例:


2
我认为您可以替换c[7]?11:c[6]?5:c[5]?3:c[4]?2:1'00011234'[c.length]||11
Arnauld

这给出了最后一个测试用例,[15,2,0]而不是[16,2,0]最后一个用例,但这很容易解决。晚餐后将继续工作,除非您发布天才的答案(通常如此)。谢谢!:)
瑞克·希区柯克

1
是的,很抱歉,应该这样'00011235'
Arnauld

1
我认为您可以像这样在@Arnauld的建议之外再节省几个字节。
毛茸茸的

1
至少有3个字母'11235'[c.length-3]||11,对不对?
JollyJoker


2

腐霉菌,26个字节

使用H.PWiz的公式

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

验证所有测试用例。

初始版本,33字节

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

验证所有测试用例。

说明

m + Fm * h +++ * 6> lk7y> lk6> lk5> glk3q1 / sQ完整程序。

m映射输入。
   m映射每个子列表。
                        > lk3长度是否大于2?如果为True,则为1;如果为False,则为0。
      +> lk5加“长度是否大于5?”。
       + y> lk6加“长度是否大于6?”,加倍。
        + * 6> lk7 Plus“长度是否大于7?”乘以6。
     h递增。
                            q1 / sQ计算展平元素的出现
                                     输入,并检查它是否等于1。如果为False,则为0,如果为True,则为1。
    *乘法。
 + F对每个子列表求和。


2

Japt29 25 24 23 21 20字节

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

试试吧


说明

数组的隐式输入U

Ëx@

在其元素通过以下函数传递后,将数组映射到数组(Ë)并通过加法(x)缩小每个子数组,其中X当前字词为。

èøX

计算(è)中U包含(ø)的元素X

¥1

检查是否等于1。

©

逻辑与(&&)。

3nXÊm8)

n从(m)8 的最小值和的长度(Ê)减去()3 X

ʬc

阶乘,平方根和四舍五入。




1

爪哇8,202个 200 198字节

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;}

或(也是198个字节

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;}

绝对可以打高尔夫球。不幸的是,Java没有内置插件或简短的方法来删除存在于多个列表中的所有列表的所有项目。

说明:

在这里尝试。

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

我喜欢三元组,而我讨厌ScaLa的唯一一件事就是他们删除了这种三元组语法。
V. Courtois

@ V.Courtois Hmm,出于好奇,现在Scala中的三元语法如何?
凯文Cruijssen

恩:if(bool1)exp1 else exp2
V. Courtois

1

R,117字节

其他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))]))

测试用例:

> 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

获取仅在列表中出现一次的名称,将其长度转换为基于给定分界点的因子,然后将其转换为分数,然后对其求和。


通过在重复数据删除步骤中结合我们的两种方法,可以得到114个字节
Giuseppe

0

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

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

在线尝试!


0

Clojure,102字节

#(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)))))

nextnil如果只有一个单词则返回w:)


0

PHP,226字节

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;}

我认为这仍然可以减少很多。

取消高尔夫:

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;
}

在线尝试!


0

斯卡拉,242字节

该函数,作为一个参数a,一个Seq[Set[String]]并返回 Array[Int]。我使用一个可变的数组(丢失了4个字符)。

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

在线尝试!

可能会感到乐观,因为我什至没有从事

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

部分。感谢您的挑战!


0

Swift 4,164字节*

{$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,+)}}

上面的表达式在技术上是正确的,纯Swift。但是,该表达式非常复杂,由于类型推断系统中的指数膨胀,在任意超时(例如15s之类)后,编译器放弃之前无法对其进行处理。

为了使该表达式可被当前的编译器编译,可以将其分解如下:

{
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 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!")
}

细分:

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字节

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.

预期数据格式为:

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

需要具有Python支持的clingo 5.2.1。

取消高尔夫:

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.

python函数受python答案的启发很大。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.