幸运屋


30

超级马里奥3D世界(Super Mario 3D World)中有一个迷你游戏,称为“ 幸运屋”。它由一个具有4个区块的老虎机组成。

幸运屋

每个块可以是5个不同的图标(花,叶,铃,樱桃或飞旋镖)之一,并且玩家的目​​标是获得尽可能多的相同图标(请参阅视频)。

玩家将获得硬币奖励,而硬币又可以转化为额外的生命。您的任务是计算获胜的额外生命数。

根据匹配的图标数量,奖励的硬币数量如下:

  • 没有匹配项-10个硬币
  • 一对-100个硬币
  • 两对-200个硬币
  • 三种-300枚硬币
  • 四种-777枚硬币

您每100个硬币赢取额外的生命(1UP)。因此,您可以肯定在一对中赢得1UP ,在两对中赢得2UP,并在同类3中赢得3UP 。但是,不匹配无法获得4种生命而赢得的生命数量取决于您最初的硬币存量。

资料来源:超级马里奥维基

输入值

您将获得初始硬币存量并获得代表老虎机上最终图标的四个值的列表。0c<100[v1,v2,v3,v4]

输出量

额外的生命的数目获得了:,,,,或。012378

规则

  • 您可以采用任何合理格式的图标:例如,列表,字符串或4个不同的参数。
  • 每个图标可以用一位整数单个字符表示。请指定答案中使用的图标集。(但是您不必解释如何将它们映射到Flower,Leaf,Bell等,因为这一点都没有关系。)
  • 不允许您重新映射输出值。
  • 这是🎰 🎰。

测试用例

在以下示例中,我们使用中的整数列表表示图标。[1..5]

coins  icons      output   explanation
-------------------------------------------------------------------------
  0    [1,4,2,5]    0      no matches  ->  0 +  10 =  10 coins -> nothing
 95    [3,1,2,4]    1      no matches  -> 95 +  10 = 105 coins -> 1UP
 25    [2,3,4,3]    1      one pair    -> 25 + 100 = 125 coins -> 1UP
 25    [4,5,5,4]    2      two pairs   -> 25 + 200 = 225 coins -> 2UP
  0    [2,5,2,2]    3      3-of-a-kind ->  0 + 300 = 300 coins -> 3UP
 22    [1,1,1,1]    7      4-of-a-kind -> 22 + 777 = 799 coins -> 7UP
 23    [3,3,3,3]    8      4-of-a-kind -> 23 + 777 = 800 coins -> 8UP
 99    [3,3,3,3]    8      4-of-a-kind -> 99 + 777 = 876 coins -> 8UP

我们是否可以将硬币计数输入为从0到0.99的浮点数?我猜不会,但以防万一。
Grimmy

1
@Grimy不,只有一个整数(或代表该整数的字符串)。抱歉回复晚了。
Arnauld

Answers:


9

x86-16组装, 56 41 39个字节

二进制:

00000000: b103 33ed ac8b fe51 f2ae 7503 45eb f983  ..3....Q..u.E...
00000010: fd03 7504 80c2 4d43 03dd 59e2 e592 7502  ..u...MC..Y...u.
00000020: 040a 3c64 7201 43                        ..<dr.C

未组装:

B1 03           MOV  CL, 3              ; set up loop counter for 3 digits
            DIGIT_LOOP: 
33 ED           XOR  BP, BP             ; clear digit matches counter in BP
AC              LODSB                   ; load next digit char into AL
8B FE           MOV  DI, SI             ; start searching at next char
51              PUSH CX                 ; save outer digit loop counter 
            MATCH_LOOP: 
F2/ AE          REPNZ SCASB             ; search until digit in AL is found 
75 03           JNZ  CHECK_FOUR         ; is end of search?
45              INC  BP                 ; if not, a match was found, increment count
EB F9           JMP  MATCH_LOOP         ; continue looping 
            CHECK_FOUR: 
83 FD 03        CMP  BP, 3              ; is four of a kind? 
75 04           JNE  SCORE_DIGIT        ; if not, add number of matches to 1UP's
80 C2 4D        ADD  DL, 77             ; add 77 to coin count 
43              INC  BX                 ; +1 1UP extra for four-of-a-kind
            SCORE_DIGIT:
03 DD           ADD  BX, BP             ; Add number of matches to total, set ZF if 0
59              POP  CX                 ; restore outer digit loop position
E2 E5           LOOP DIGIT_LOOP         ; keep looping
92              XCHG DX, AX             ; coin count to AX for shorter compare
75 02           JNZ  FINAL_SCORE        ; if 1UPs > 0, no consolation prize
04 0A           ADD  AL, 10             ; award 10 coins
            FINAL_SCORE:
3C 64           CMP  AL, 100            ; is coin score over 100?
72 01           JB   DONE               ; if not, no extra 1UP
43              INC  BX                 ; otherwise, increment 1UP
            DONE:

在中输入起始硬币计数DXSI指向“图标”字节(可以是'1'- '5'或任何字节值)的开始。在中输出1UP的数量BX

说明:

对四个字节的输入进行迭代,并将其与右边的其余字节进行比较,计算匹配数。每种比赛类型的分数均被授予并加总。由于四分之一也是三分之一也是一对,因此每种得分类型的值可以按以下方式分解:

  • 3个匹配= 4个1UP + 77个硬币
  • 2场比赛= 2 1UP
  • 1场比赛= 1 1UP

例子:

[2, 2, 2, 2] (四种)= 7个1UP + 77个硬币

2 [2, 2, 2] = 3 matches = 4 1UP's + 77 coins
   2 [2, 2] = 2 matches = 2 1UP's
      2 [2] = 1 match   = 1 1UP

[2, 5, 2, 2] (三种)= 3 1UP

2 [5, 2, 2] = 2 matches = 2 1UP's
   5 [2, 2] = 0 matches
      2 [2] = 1 match   = 1 1UP

[4, 5, 5, 4] (两对)= 2个1UP

4 [5, 5, 4] = 1 match   = 1 1UP
   5 [5, 4] = 1 match   = 1 1UP
      5 [4] = 0 matches

[2, 3, 4, 3] (一对)= 1 1UP

2 [3, 4, 3] = 0 matches
   3 [4, 3] = 1 match   = 1 1UP
      4 [3] = 0 matches

如果最后获得的1UP的数量为0,则将奖励10个硬币。如果总硬币数大于100,则额外奖励1UP。

这是PC DOS的测试程序,其中包括处理整数值I / O的额外例程:

在此处输入图片说明

下载并测试LUCKY.COM for DOS。


5

果冻 23 22 20  19 字节

-1得益于Outgolfer的Erik³代替ȷ2),在新版本中也使用了两次
-1得益于Grimy(在求和前减去一个,而不是在其后减去四)

也许是可击败的?

ċⱮ`’SṚḌH׳«777»⁵+:³

接受列表和生成整数的整数的二元链接。

在线尝试!或见一个测试套件

怎么样?

ċⱮ`’SṚḌH׳«777»⁵+:³ - Link: list a, integer n   e.g. [x,x,x,x], 22
 Ɱ`                 - map across a with:
ċ                   -   count occurrences in a       [4,4,4,4]
   ’                - decrement                      [3,3,3,3]
    S               - sum (call this s)              12
     Ṛ              - reverse (implicit toDigits)    [2,1]
      Ḍ             - un-decimal                     21
       H            - halve                          10.5
         ³          - 100                           100
        ×           - multiply                     1050
           777      - 777                           777
          «         - minimum                       777
               ⁵    - 10                             10
              »     - maximum                       777  (handles 0 -> 10)
                +   - add (n)                       799
                  ³ - 100                           100
                 :  - integer division                7

每种手牌的手牌评估如何工作:

           Hand:    no-pair     pair        2-pair      trips       4-of-a-kind
(sorted) counts:    [1,1,1,1]   [1,1,2,2]   [2,2,2,2]   [1,3,3,3]   [4,4,4,4]
      decrement:    [0,0,0,0]   [0,0,1,1]   [1,1,1,1]   [0,2,2,2]   [3,3,3,3]
            sum:    0           2           4           6           12
       reversed:    [0]         [2]         [4]         [6]         [2,1]
     un-decimal:    0           2           4           6           21
         halved:    0           1           2           3           10.5
      times 100:    0           100         200         300         1050
    min(x, 777):    0           100         200         300         777
     max(x, 10):    10          100         200         300         777

备选方案20: ĠẈị“¡ıKĖ‘S×4+E{»⁵+:³


您可以通过假定该函数所在的程序中不包含命令行参数替换ȷ2³,尽管我认为这不是“好运”的意思。:P
的Outgolfer埃里克

谢谢埃里克,是的,这不是我认为会被打败的方式^^
乔纳森·艾伦

-1字节(感谢肮脏的我05AB1E端口由1相加之前先降计数)。而不是先加总,ċⱮ`’SṚḌH׳«777»⁵+:³
再减

谢谢@KevinCruijssen稍后会更新(很好的工作,再次令人毛骨悚然!)
乔纳森·艾伦

4

Zsh117 ... 60字节

-13使用不同的区分标准,-9通过合并大小写,-9 -28通过将case语句更改为嵌套算术三元,-4感谢@JonathanAllan,-1通过优化三元,-2因为我echo在添加时不小心使用了乔纳森的优化。

接受stdin上的硬币计数,并阻止输入作为参数。参数可以是数字,字符甚至字符串:./foo.zsh flower leaf flower boomerang

read c
for i;for j;((a+=i<j))
<<<$[!a?7+(c>22):a-6?6-a:c>89]

在线尝试: 117 104 95 67 63 62 60

这是67字节答案中的魔术:

read coins
for block                  # for each element
  (( a+=${#${@:#$block}} ))
#          ${@:#$block}      remove all elements which don't match
#       ${#            }     count the remaining elements
# (( a+=                 ))  add that number to the total
<<<$[a?(a-12?6-a/2:coins>89):7+(coins>22)]
#    a?                     :7+(coins>22)  4*0 (all elements match all elements)
#      (a-12?     :coins>89)               4*3 (all elements match exactly one)
#      (a-12?6-a/2         )               3*1 + 1*3 ->  6, 6 -  6/2 -> 3
#                                          2*2 + 2*2 ->  8, 6 -  8/2 -> 2
#                                          2*3 + 2*2 -> 10, 6 - 10/2 -> 1


3

Python 2,63个字节

lambda x,l:int([3,1,7.77,2,.1][sum(map(l.count,l))%14%5]+x/1e2)

在线尝试!

我有和GammaFunction相同的想法,可以sum(map(l.count,l))用作“指纹”。但是,我没有在结果上使用算术公式,而是使用查找表,首先使用mod链将值压缩为0到4 %14%5。将所有点值除以100可节省几个字节。


Python 3中有62个字节
Arnauld

或单个Mod的61个字节
Arnauld

(嗯...没有注意到,它实际上是什么无知的实施方案正在做。)
阿尔诺

3

Python 3,68个字节

def f(c,a):x=sum(map(a.count,a))//2;return[c//90,x-2,7+(c>22)][x//3]

在线尝试!

我的Zsh答案的Bash端口的C端口的C端口的Python端口,在“ Python高尔夫技巧”页面的帮助下进行了重新讨论。最后一个端口,我发誓...我的语言用尽了,我很喜欢打高尔夫。与其他Python答案相比,我很好奇这种策略。再次,可能有一些方法可以克服这个问题。

这个结果出奇的好,所以我在下面添加了一张表格,总结了正在发生的事情,以便其他人可以移植或改进它。

Type          Example  map(a.count,a)  sum(__)   x=__//2  x//3   array lookup
----------------------------------------------------------------------------
none         [1,2,3,4]    [1,1,1,1]        4       2       0      c//90
pair         [1,1,2,3]    [2,2,1,1]        6       3       1      x-2 -> 1
two pair     [1,3,1,3]    [2,2,2,2]        8       4       1      x-2 -> 2
3-of-a-kind  [1,3,1,1]    [3,1,3,3]       10       5       1      x-2 -> 3
4-of-a-kind  [3,3,3,3]    [4,4,4,4]       16       8       2      7+(c>22)

Python 3.8(预发布),63字节

赞美:=海象!

lambda c,a:[2+c//90,x:=sum(map(a.count,a))//2,9+(c>22)][x//3]-2

在线尝试!



3

Python 2中96个 91 89字节

-2个字节,感谢@Kevin Cruijssen

lambda x,a,b,c,d:(x+(100*sum((a==b,a==c,a==d,b==c,b==d,c==d))or 10)+177*(a==b==c==d))/100

在线尝试!


啊。我错过了。谢谢。
Hiatsu

您可以删除一对括号(100*sum((a==b,a==c,a==d,b==c,b==d,c==d))-2个字节。
凯文·克鲁伊森

3

PHP,153127字节

@ 640KB进行了一些非常聪明的更改,以进一步缩短它:

function($c,$s){for(;++$x<6;$n+=$m>3?777:($m>2?300:($m>1)*100))for($m=!$y=-1;++$y<5;$m+=$s[$y]==$x);return($c+($n?:10))/100|0;}

在线尝试!


1
@XMark大家好,欢迎来到CGCC!不错的提交!我打了些高尔夫球,然后让您得到-26字节127字节,TIO。让他们来吧!
640KB



2

Perl -pF 5,46个字节

map$q+=$$_++,@F;$_=0|<>/100+($q>5?7.77:$q||.1)

在线尝试!

输入的第一项是旋转结果,使用任何5个唯一的ASCII字母q(我建议除外abcde)。输入的第二行是当前硬币计数。

怎么样?

-F     # CLI option splits the input into individual characters in @F
map
   $q+=   # $q holds the result of the calculation here
          # possible values are 0,1,2,3,6
   $$_    # This interprets $_ as a variable reference, thus if $_ is 'a', this variable is $a
   ++     # increment after adding it to $q
,@F;      # iterate over the elements of @F
$_=0|     # force the result to be an integer
   <>/100 # divide the current coin count by 100
   +($q>5?7.77  # if $q is over 5, then there must have been 4 of a kind
   :$q||.1)     # otherwise, use $q, unless it is 0, then use .1
-p        # CLI option implicitly outputs $_

所有涉及的数字都除以100,因此该程序正在计算当前获得的生命(包括部分生命)的数目。解决方案的诀窍在中map。如果可能的条目abcde,那么每个的$a$b$c$d,和$e持有的时间这个角色以前曾见过数的计数。$q每当看到一个字符时,该值就会添加到运行总计()中。如果有四个同类(实际上是177个硬币奖励),则运行总额会增加。


1
请您说明一下其工作原理吗?
msh210

@ msh210我已尝试尽我所能添加一个。请随时提问。
Xcali

2

JavaScript(Node.js),64字节

c=>a=>[,7.77,a.sort()[1]-a[2]?2:3,1,.1][new Set(a).size]+c*.01|0

在线尝试!

我认为必须至少有一个JavaScript答案才能应对Arnauld挑战!

这里的概念主要是使用不同元素的数量作为查找关键字。

  • 1个唯一=> 4个同类
  • 2个唯一=> 2对或3种
  • 3个唯一=> 1对
  • 4个唯一=>没有匹配项

为了区分2对和3对,对输入数组进行排序并比较中间的2个元素。


2

PHP89 84字节

foreach(count_chars($argv[2])as$a)$b+=[2=>1,3,7.77][$a];echo$argv[1]/100+($b?:.1)|0;

在线尝试!

从命令行输入,输出到STDOUT

$ php lucky.php 99 3333
8

$ php lucky.php 0 2522
3

$ php lucky.php 0 abaa
3

1

Stax,23 个字节

¿^∩û:¶á☺ⁿ£z⌐└≤♂EM¥t(,5╓

运行并调试

该程序使用任意的5个整数集作为图标。

程序:

  1. 总计每个元素的出现次数。
  2. 除以2,然后除以7。
  3. 结果是一个来自1..5的数​​字。使用它可以以固定的阵列查找硬币奖品。
  4. 添加到初始硬币计数。
  5. 除以100。

这是我正在为下一版stax进行实验的堆栈状态可视化器的输出。这是同一代码的解压缩版本,其中堆栈状态已添加到注释中。

c               input:[2, 3, 4, 3] 25 main:[2, 3, 4, 3] 
{[#m            input:[2, 3, 4, 3] 25 main:[1, 2, 1, 2] 
|+              input:[2, 3, 4, 3] 25 main:6 
h7%             input:[2, 3, 4, 3] 25 main:3 
":QctI*12A"!    input:[2, 3, 4, 3] 25 main:[300, 777, 10, 100, 200] 3 
@               input:[2, 3, 4, 3] 25 main:100 
a+              main:125 [2, 3, 4, 3] 
AJ/             main:1 [2, 3, 4, 3] 

运行这个


1

视网膜0.8.2,72字节

O`\D
(\D)\1{3}
777¶
(\D)\1\1
300¶
(\D)\1
100¶
\D{4}
10¶
\d+\D*
$*
1{100}

在线尝试!链接包括测试用例。将输入作为4个可打印的ASCII非数字,然后是数字的硬币初始数量。说明:

O`\D

对非数字排序,以便将相同的符号分组在一起。

(\D)\1{3}
777¶

四分制777分。

(\D)\1\1
300¶

同类三分300。

(\D)\1
100¶

每对得分100,因此两对得分200。

\D{4}
10¶

如果没有比赛,那么您仍然会赢!

\d+\D*
$*

将值转换为一元并取和。

1{100}

整数将总和除以100,然后转换回十进制。


1

视网膜,56字节

(\D)\1{3}
777¶
w`(\D).*\1
100¶
\D{4}
10¶
\d+\D*
*
_{100}

在线尝试!链接包括测试用例。将输入作为4个可打印的ASCII非数字,然后是数字的硬币初始数量。说明:

(\D)\1{3}
777¶

四分制777分。

w`(\D).*\1
100¶

每对得分为100。w考虑到所有对,因此它们可以交织在一起,另外,三个同类可以分解为三对,从而自动得分300。

\D{4}
10¶

如果没有比赛,那么您仍然会赢!

\d+\D*
*

将值转换为一元并取和。

_{100}

整数将总和除以100,然后转换回十进制。




1

C(gcc)92 84 82 81 79 78字节

-1通过x+=(..!=..) -5通过经由分配返回-4由于乔纳森艾伦通过更换!=<,而在其他地方保存字节,-1通过重新排列三元。

在@ceilingcat中:-2通过声明ix在函数外部;-1则通过设置x=i和减量x

i,x;f(c,a)int*a;{for(i=x=16;i--;)x-=a[i/4]>=a[i%4];c=x?x-6?6-x:c>89:7+(c>22);}

我的Zsh答案的另一个端口。我不熟悉C高尔夫,这里可能还有另一个技巧可以进一步降低它。 92 84 82 81 79 在线试用!


1
使用小于代替不等于节省4:x+=a[i/4]<a[i%4];c=x?(x-6?6-x:c>89):7+(c>22);
Jonathan Allan

1

05AB1E20 19 18 字节

D¢<OR;т*777T)Åm+т÷

@JonathanAllan的Jelly答案端口,因此请确保对他进行投票!!
-2个字节感谢@Grimy

将图标列表作为第一个输入(是[1,2,3,4,5]),将硬币数量作为第二个输入。

在线尝试验证所有测试用例。(测试套件使用T‚à+代替TMI+,这是一个相等的字节替代方案。)

说明:

D                   # Duplicate the first (implicit) input-list
 ¢                  # Count the amount of occurrences in itself
  <                 # Decrease each count by 1
   O                # Sum these
    R               # Reverse it
     ;              # Halve it
      т*            # Multiply by 100
        777         # Push 777
           T        # Push 10
            )       # Wrap all three values into a list
             Åm     # Get the median of these three values
               +    # Add the second (implicit) input to it
                т÷  # And integer-divide it by 100
                    # (after which the result is output implicitly)

@肮脏的啊,当然。谢谢!我在果冻答案中建议使用相同的高尔夫方式(当然要给您信用)。:)
凯文·克鲁伊森

1
777‚ßTMI可以777T)Åm
Grimmy

Cheaty 17(将硬币计数视为浮动的,我敢肯定这是不允许的)
Grimmy

@Grimy那么在这种情况下0.9090硬币吗?由于硬币输入[0,99]肯定在此范围内,因此您可以询问OP他是否允许输入。
凯文·克鲁伊森

是的,0.90表示90个硬币。我问OP。无论如何,这是另一个不作弊的18
Grimmy


1

木炭,30字节

≔⊘ΣEη№ηιηI⌊⁺∕θ¹⁰⁰∨⁻η∕²∨›⁸η⁹∕¹χ

在线尝试!链接是详细版本的代码。将输入作为硬币数量,并将任何Python可比较值的数组作为图标。说明:

≔⊘ΣEη№ηιη

无耻地窃取@GammaFunction的计算计数总和一半的技巧。

⁻η∕²∨›⁸η⁹

2从总和中减去,从而得出0, 1, 2, 3适当的值,但对于4种类型,请先将其2除以9,得到7.777...

∨...∕¹χ

但是,如果结果为0,则没有匹配项,因此将其0.1替换为。(在这里使用文字对我没有帮助,因为我需要一个分隔符。)

I⌊⁺∕θ¹⁰⁰...

将初始硬币除以100,再加上奖金,然后将结果取整并转换为字符串以进行隐式输出。


1

Pyth,32个字节

AQ-@[+K2/G90J/sm/HdH2+9>G22)/J3K

在线尝试!

受到GammaFunction解决方案的启发。将输入作为[coins, [icons]]

AQ                               # Q is the input. Set G := Q[0], H := Q[1]
    [                      )     # Construct a list from the following entries:
     +K2/G90                     # [0] (K:=2) + G/90 (/ is integer division)
            J                    # [1] J:=
              s                  #        reduce on + (
               m   H             #          map entries of H as d on (
                /Hd              #            number of occurences of d in H ) )
             /      2            #                                               / 2
                     +9>G22      # [2] 9 + (G > 22)
   @                        /J3  # Take element at position J/3
  -                            K # Subtract K (=2)

1

PowerShell,94字节

param($n,$l)$r=@{2=100;3=300;4=777}[($l|group|% c*t)]|?{$_;$n+=$_}
+(($n+10*!$r)-replace'..$')

在线尝试!

展开:

param($nowCoins,$values)
$groupCounts=$values|group|% count
$rewardedCoins=@{2=100;3=300;4=777}[$groupCounts]|?{
    $_                          # output matched only
    $nowCoins+=$_               # and accumulate
}
$nowCoins+=10*!$rewardedCoins   # add 10 coins if no rewarded conis
+($nowCoins-replace'..$')       # truncate last two digits

1

PowerShell中114个 107字节

-7个字节,感谢mazzy

param($n,$l)((((0,.1,1)[+($x=($l|group|% c*t|sort))[2]],2,3)[$x[1]-1],7.77)[$x[0]-eq4]+".$n")-replace'\..*'

在线尝试!

PowerShell风格的大型三元运算基于对输入列表的计数进行分组和排序。之所以需要进行排序,是因为我们利用了这样一个事实,即分组列表越短,重复次数越多。实际上,这是所有可能的值:

(1,1,1,1)
(1,1,2)
(2,2)
(1,3)
(4)

截断为int仍然很昂贵。

展开:

param($n,$l)
$x=$l|group|% c*t|sort
(((                      #Start building a list...
   (0,.1,1)[+$x[2]],     #where spot 0 holds dummy data or handles no match and 1 pair
    2,3)[$x[1]-1],       #Overwrite the dummy data with 2-pair or 3-o-k
   7.77)[$x[0]-eq4]      #OR ignore all that and use spot 1 because it's a 4-o-k
   +".$n"                #Use that value and add CoinCnt via int-to-string-to-decimal
)-replace'\..*'          #Snip off the decimal part

1
是允许使用空字符串0吗?在线尝试!
mazzy

1
另一种变体在线尝试!
mazzy


1

R,10291,81个字节

f=function(b,v,s=table(v))(477*any(s>3)+b+10*all(s<2))%/%100+sum(s==2)+3*any(s>2)

感谢@Giuseppe,成功删除了11个字节(并修复了一个错误)。受@Giuseppe / 10思想启发,又管理了10个人。

不打高尔夫球

f=function(b,v){
  s = table(v)          #included in fn inputs
  a = b+10*all(s<2)     #covers all different case
  a = a+477*any(s>3)    #Covers 4 of a kind
  d = sum(s==2)+3*any(s>2) #covers 1 and 2 pair, 3 of a kind.
  a%/%100+d         #sum appropriate values
}

在线尝试!


1
这似乎没有通过最后一个测试用例
朱塞佩

1
但是如果您能找出原因,则可以删除as.factor()和,f=使其达到88字节。
朱塞佩

啊-不错,我的数学似乎做错了。最重要的一点table-我不应该熟悉-我开始了summary(as.factor(v))。我宁愿离开f=。没有它,我感觉代码并不完整,但是我意识到这是一种样式选择。
user5957401

如果你这么说。这是87个字节,包括f=; 随时将TIO链接放入您的答案:-)
朱塞佩

我喜欢分开。当我玩弄它时,我发现这sum(s==2)很有帮助。但这需要重写其他所有内容,并且/ 10不再节省空间(我不认为)
user5957401

0

8051汇编(编译为158个字节)

这是VEEEEEEEEEERRY天真的方式,尚未经过测试和验证,但我非常有信心。要考虑的事情是:

1)8051是蓄能器,即 它需要其他架构可能根本不需要的mov指令。

2)8051是一台8位计算机,因此对于> 255的数字必须做一些技巧,这会产生更多的代码,因此该平台相对于其他平台而言是一个缺点。

CSEG AT 0000H

coinStackOnes equ 0xf3
coinStackTens equ 0xf4
coinStackHundreds equ 0xf5 ; leave one byte as guard so that if that gets corrupted it doesnt really matter

values1 equ 0xf7
values2 equ 0xf8
values3 equ 0xf9
values4 equ 0xfa

numOfFlowers equ 0xfb
numOfLeaf equ 0xfc
numOfBell equ 0xfd
numOfCherry equ 0xfe
numOfBoomerang equ 0xff

flower equ 1
leaf equ 2 
bell equ 3
cherry equ 4
boomerang equ 5

numOfHeartsReceived equ 0xf1

mov r1, #4
mov r0, numOfFlowers
clearNumOfRegs: mov @r0, #0d
        inc r0
        djnz r1, clearNumOfRegs
;if you reach this all numOfXXXX registers are zeroed

mov r0, #values1 
mov r1, #flower

mov a, #6 ; innercounter
mov b, #5 ; outercounter
checkfornextpossibleitem:   mov r2, a; backup countervar
                mov a, @r0 ; store given value in a
                xrl a, @r1 ; xor a with item
                jnz nextItem ; if value!=item -> nextitem
                mov a, #numOfFlowers ;if you end up here a=0 (ie value == item) --> generate addr for numOfReg <-- load a with addr for numOfFlowers
                add a, r1 ; since items are only numbers you can add the item to get the addr for numOfReg a=addr(numOfReg)
                xch a, r1 ; change the item with the addr as r1 is indirect register
                inc @r1 ; increment numOfRegister
                xch a, r1; r1 = item
                ;next item              
                nextItem:   inc r1 ; increment item
                        mov a, r2 ; restore counter
                        dec a; decrement counter
                        cjne a, #0, checkfornextpossibleitem 
                        ;if you reach this you have successfully tested one value against all items and therefor the next value must be tested
                        mov a, #6; reset the innercounter
                        dec b; decrement the outercounter
                        inc r0; increment the register that points to the value-under-test
                        xch a,b; cjne works with a but not with b therefor exchange them
                        cjne a, #0, here ; do the comparison; if you dont jump here you have tested all values 
                        jmp howManyPairsDoIHave; if you didnt jump above you have the now the number of flowers and so on
                        here:   xch a,b ; and change back
                            jmp checkfornextpossibleitem ; check the next value
howManyPairsDoIHave:    mov r0,#0; store numOfPairsHere initialize with zeros
            mov r1, numOfFlowers; 
            mov b, #6; use as counter to know when you went through all numOfRegisters
analyseNumOfRegister:   mov a, @r1 ; load the numOfregister for some math
            xrl a, #2; a will contain zero if numOfXXX = 2
            jnz numOfXXXWasNot2; if you do not jump here you have 2 XXX therefor 
            inc r0; increment the number of pairs
            jmp nextNumOfRegister; continiue with the next one
            numOfXXXWasNot2:    mov a, @r1; restore the number of XXX and try the next magic value
                        xrl a, #3; will contain zero if you have a three of a kind                      
                        jnz no3XXX; if you dont jump here however you have a three of a kind
                        jz add300Coins
                        no3XXX:     mov a, @r1; restore number of XXX
                                xrl a, #4; a will contain zero if 4 of a kind
                                jnz nextNumOfRegister; if you numOfXXX!=4 you can only continiue trying to find something in the next numof register
                                jz add777Coins; if you didnt jump above how ever you will have to add the 777 coins as you detected a 4 of a kind
nextNumOfRegister:  inc r0; move pointer to the next numofregister
            djnz b, analyseNumOfRegister; if you havent already analysed all numofregisters then continue
            ; if you have however you end up here so you will have to take a look at the numOfPairs
            cjne r0, #1, tryIf2Pairs; test if you have 1 pair if not try if you have 2
            jmp add100Coins; if you have 1 pair however add the 100 coins
            tryIf2Pairs:    cjne r0, #2, youMustHave0Pairs; test if you have 2 pairs if not you can be sure to have 0 of them
                    jmp add200Coins; if you have 2 pairs however add them
youMustHave0Pairs:  ; add 10 coins
            inc coinStackTens
            mov a, coinStackTens
            cjne a, #10d, howManyHearts ; if your tens digit isnt outta range continue with the calculation of the number of hearts
            inc coinStackHundreds; if it is outta range do correct that
            mov coinStackTens, #0
            jmp howManyHearts;
add100Coins:    inc coinStackHundreds; here the digit can not possibly have an invalid value...
        jmp howManyHearts
add200Coins:    mov a, coinStackHundreds
        add a, #2
        mov coinStackHundreds, a
        jmp howManyHearts ; also here no invalid values possible
add300Coins:    mov a, coinStackHundreds
        add a, #3
        mov coinStackHundreds, a
        jmp howManyHearts ; same again
add777Coins:    mov r0, #coinStackOnes
        mov r2, #3
add7:       mov a, r0
        mov r1, a
        mov a, @r0
        add a, #7
        mov b, a; b contains the possibly invalid version of the ones digit     
        da a; if you have an invalid value its lower nibble gets corrected this way
        anl a, 0x0f; and the higher one gets corrected this way
        xch a,b; a and b must be swapped in order to make subb work ie b contains now the corrected value and a has the maybe faulty value
        subb a,b; returns zero if all the corrections had no effect therefor the next digit can be increased by 7
        jz nextDigit
        inc r1
        inc @r1
        nextDigit:  inc r0
                djnz r2, add7;

howManyHearts:  mov numOfHeartsReceived, coinStackHundreds
loop_forever:   sjmp loop_forever
        END
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.