我撕了多少页?


34

上个月,我从图书馆借了很多书。他们都是好书,充满了情感和情节扭曲。不幸的是,有时我会非常生气/悲伤/失望,所以我撕了一些纸。

现在图书馆想知道我为每本书撕了多少页。

您的目标是编写一个程序,该程序以逗号分隔的数字列表作为输入,并打印我可能撕裂的最小和最大页数。每行代表一本书,每个数字代表该书中缺少的一页。

输入示例:

7,8,100,101,222,223
2,3,88,89,90,103,177
2,3,6,7,10,11
1
1,2

输出示例:

4/5
5/6
3/6
1/1
1/2

4/5表示我可能已经撕掉4页或5页,具体取决于这本书的页码从哪一侧开始。一个人可能已经撕掉了6/7页,8/9页,100/101页和222/223页(4页)。或者,可以撕下第7/8页,第99/100页,第101/102页,第221/222页和第223/224页(5页)。

请记住,书页总是有正面和反面。本书的页码也不同。有些书的左页有偶数页码。一些在正确的页面上。从左到右阅读所有书籍。

以字节为单位的最短代码获胜。在严格的I / O格式不是必需的。您的程序必须能够将一本或多本书籍作为输入。玩得开心。


3
如果不能保证对输出值进行排序,是否可以接受?(例如4/55/4
Arnauld

不要忘记更新挑战以指定输出顺序必须一致,无论是全部min/max还是全部max/min。(不过,就我个人而言,我希望不要成为规范的一部分!)
Shaggy

2
programs must be able to take one or more books as input统治的理由是什么?大多数(如果不是全部)将只包装代码以将单本书验证为循环或其他内容。恕我直言,这只会增加答案的开销,而对挑战却几乎没有收益。这个问题已经有了很多答案,因此最好保持原样,但请记住这一点,以应对未来的挑战。
Rod

建议的测试用例(由@Arnauld提供):1,3,5,7,9,11,13,15,17,18-对于那些sort默认情况下内置方法按词典顺序进行排序的语言(假定对规范一致地输出的要求添加),这有利的。
毛茸茸的

Answers:


6

05AB1E,13个字节

εD>)ÅÈε€θγg}{

在线尝试!

感谢Emigna对规范更改的注意。

说明

εD>)ÅÈε€θγg}{ – Full program.
ε             – For each book...
 D            – Push two copies of it.
  >           – Increment all the elements of the second copy.
   )          – Wrap the whole stack into a list.
    ÅÈ        – Produces the lists of even natural numbers lower or equal to each element.
      ε       – For each (the modified copies of the book):
       €θ     – Get the last item of each.
         γg   – And split into chunks of equal adjacent elements.
           }  – Close the loop.
            { – Sort the resulting list.

不错的提交。我用2条额外的输入/输出线更新了挑战。同样,不需要严格的I / O。
arminb

顺便说一句,您的程序不会将多本书作为输入。
arminb

@Emigna感谢您的注意。相应地编辑了我的答案。
Xcoder先生18年

@arminb现在应该修复。
Xcoder先生18年

4

Python 2中72个 56 68 67字节

lambda b:[map(len,map(set,zip(*[[p/2,-p/2]for p in t])))for t in b]

在线尝试!


您的程序不接受多行输入(多本书)。我用2条额外的输入/输出线更新了挑战。同样,不需要严格的I / O。
arminb

1
每次运行是否有多个输入不属于严格的I / O?
Rod

1
一个人可以争论。
arminb

I / O规范涵盖了如何将书籍及其页面作为输入。你要求不要采取多本书籍作为输入是挑战规范的一部分。
毛茸茸的

4

JavaScript,104 93 92 85 80 79 74字节

57个字节,如果不是为了不必要的(在我看来)的要求,即在输出的每一对数字将持续整理,或47个字节,如果我们只需要取一本书作为输入。

输入和输出都是数组的数组。

a=>a.map(x=>[0,1].map(n=>new Set(x.map(y=>y+n>>1)).size).sort((x,y)=>x-y))
  • 最初是受Olivier的Java解决方案和我自己的(当前已删除)Japt解决方案启发。
  • 感谢Arnauld(节省了2个字节)(加上我们同时发现的另外3个字节),感谢他发现了损坏的排序,又增加了 10个字节,我希望在这个需求还在讨论中时,没人希望您能注意到!

测试用例

测试用例被分为几本书,以提高可读性,最后一个案例(包括[1,2]边缘案例)用来说明该解决方案在输入中支持多本书。

f=
a=>a.map(x=>[0,1].map(n=>new Set(x.map(y=>y+n>>1)).size).sort((x,y)=>x-y))
o.innerText=` Input                         | Output\n${`-`.repeat(31)}|${`-`.repeat(21)}\n`+[[[7,8,100,101,222,223]],[[2,3,88,89,90,103,177]],[[2,3,6,7,10,11]],[[1,3,5,7,9,11,13,15,17,18]],[[1],[1,2],[8,10]]].map(b=>` `+JSON.stringify(b).padEnd(30)+"| "+JSON.stringify(f(b))).join`\n`
<pre id=o></pre>


历史


没有写到输出必须从最小到最大排序。问题仅表明输入将被排序。
奥利维尔·格雷戈尔

@OlivierGrégoire; 而真正使输出的一致排序目前并未包括在规范中,arminb有评论一对夫妇的解决方案,指出它确实的要求。我已经对要求将其包括在内的挑战发表了评论,并表示我反对它-毕竟,对我而言,这将属于严格的I / O。
毛茸茸的

1
我认为这应该适用于64个字节。但是,当前没有任何回调的排序方法存在缺陷。它将失败,例如[1,3,5,7,9,11,13,15,17,18]
Arnauld

谢谢,@ Arnauld。刚写完要映射的更新,[0,.5]而不是g在发现您的评论时使用。不知道为什么我对按位运算符有这样的想法!我希望输出排序不会成为必需,并且sort()在此期间没有人会注意到我的坏处;)需要做一些工作,因此需要一段时间才能进行更新。
毛茸茸的

@Shaggy的初衷是y/2什么?对于此算法,将页码分为两半的原因是什么?
MicFin

2

视网膜0.8.2,60字节

\d+
$*
.+
$&,/$&,
,(?=.*/)
1,
((11)+,)1\1|1+,
1
%O`1+
1+
$.&

在线尝试!说明:

\d+
$*

将页码转换为一元。

.+
$&,/$&,

复制列表,插入/

,(?=.*/)
1,

在列表的一份副本中增加页码。

((11)+,)1\1|1+,
1

计算页数,但是连续的偶数和奇数仅算作一页。

%O`1+

按顺序对计数进行排序。

1+
$.&

将计数转换回十进制。


不错的提交!我用2条额外的输入/输出线更新了挑战。同样,不需要严格的I / O。看来您的程序是目前唯一通过所有测试用例的程序。
arminb

不能,(?=.*/)¶1,像这样,.*/¶1$&吗?
Ven

@Ven不,那只会增加一个数字,但我需要增加所有这些数字。
尼尔,

好了,并且使用重叠拿着它回到了相同的字节数,那么公平这份厚礼
法师

2

Haskell,62个字节

import Data.List
p t=sort[length$nub[div(p+o)2|p<-t]|o<-[0,1]]

在线尝试!


1
我不认为这在技术上是有效的,因为该问题需要完整的课程(Your goal is to write a program, which takes a sorted, comma-delimmited list of numbers as input
很有可能

@Ourous是的。我还用2条额外的输入/输出线更新了挑战。同样,不需要严格的I / O。
arminb

2

Java(OpenJDK 9),163字节

import java.util.*;
n->{for(int i=n.length;i-->0;){Set s=new HashSet(),t=new HashSet();for(int p:n[i]){s.add(p/2);t.add(++p/2);}n[i]=new int[]{s.size(),t.size()};}}

在线尝试!

说明

n->{                                   // Input-output of int[][]
 for(int i=n.length;i-->0;){           // Iterate on books
  Set s=new HashSet(),t=new HashSet(); // Create two hashsets
  for (int p:n[i]) {                   // Iterate over each page
   s.add(p/2);                         // Add the sheet-of-page of books [ even | odd ] to one set.
   t.add(++p/2);                       // Add the sheet-of-page of books [ odd | even ] to the other set.
  }
  n[i]=new int[] {                     // change the input to the number of sheets used.
   s.size(),
   t.size()
  };
 }
}

注意:由于对此没有要求,因此不对最小页数和最大页数进行排序。


size可以add在Java中链接以节省一些字节吗?例如s.add(p/2).size
毛茸茸的

1
@Shaggy不。我可以将内容与流链接起来,但这会增加很多字节,而不是保存;-)
OlivierGrégoire18年

2

APL(Dyalog Unicode),37字节

{(≢⍵)≤2:⌽≢∘∪¨⌊⍵(1+⍵)÷2⋄≢∘∪¨⌊⍵(1+⍵)÷2}

在线尝试!

如果页面的输出顺序无关紧要,则可以用不到一半的字节数来完成此操作:

{≢∘∪¨⌊⍵(1+⍵)÷2}

怎么样?

{(≢⍵)≤2:⌽≢∘∪¨⌊⍵(1+⍵)÷2⋄≢∘∪¨⌊⍵(1+⍵)÷2}⍝ Prefix dfn
{(≢⍵)≤2:                                If argument length 2 
                    ÷2                  Divide by 2
              ⍵(1+⍵)                    Both the argument and 1+argument
                                       Round down to the nearest integer
           ∪¨                           Get the unique values of each
                                       And then
                                       Get the tally of elements of each
                                       And reverse the result
                                       Else
                       ≢∘∪¨⌊⍵(1+⍵)÷2}  Same as above, without reverting the result.


2

Perl 5,95 +1(-a)= 96字节

@0=@1=0;map{$i=-1;$F[$i]+1==$F[$i+1]&&$F[$i]%2==$_&&$i++while++$i<@F&&++@{$_}[0]}0,1;say"@0/@1"

在线尝试!


在某些情况下,您的程序无法正确执行。我用2条额外的输入/输出线更新了挑战。同样,不需要严格的I / O。
arminb

我看不到您的任何测试用例都在哪里失败。唯一不起作用的是多个案例,这些案例是在我发布解决方案很久之后添加的。无论如何,我已经更新了解决方案以处理多个测试。
Xcali

2

Wolfram语言(Mathematica),37个字节

感谢@MartinEnder 8个字节!

Sort[Length@*Split/@{#,#+1}~Floor~2]&

在线尝试!

说明

在: {3, 4, 5}

{#,#+1}

取(输入)和(输入+1)。 {{3, 4, 5}, {4, 5, 6}}

... ~Floor~2

对于上方的每个数字,请减去最大的偶数。 {{2, 4, 4}, {4, 4, 6}}

Length@*Split/@

对于上方的每个列表,请按相同元素拆分列表 {{{2}, {4, 4}}, {{4, 4}, {6}}}

并取每个的长度: {2, 2}

Sort[ ... ]

排序输出。


1
您不需要SplitByLength@Split@⌊#/2⌋&/@{#,#+1}&有效。但后来它甚至更短的地图之前做地板:Length@*Split/@⌊{#,#+1}/2⌋&。而且,如果您愿意,也可以不使用Unicode获得相同的字节数:Length@*Split/@{#,#+1}~Floor~2&
Martin Ender

嗯,我认为挑战需要严格的I / O格式。
暴民埃里克(Erik the Outgolfer)'18年

1

干净222个 210 204 196字节

import StdEnv,ArgEnv,Data.Maybe,qualified GenLib as G
Start=tl[let(Just l)='G'.parseString i;?s=sum[1\\n<-[s,s+2..last(sort l)]|isAnyMember[n,n+1]l]in zip2(sort[?0,?1])['/\n']\\i<-:getCommandLine]

在线尝试!

完整的程序要求绝对会破坏Clean的竞争能力。

对于那些一直关注我在Clean中的答案的人,您会注意到import qualified,这是一个丑陋的技巧,可以绕开不应该一起使用的模块一起使用-仅在这里需要这样做,因为还有另一个丑陋的技巧要做与GenLib根据Data.Maybe,而不是StdMaybe,这是结果丑陋的黑客从Haskell的翻译库Data获得功能清洁自己的图书馆也同样完成之前。

通过命令行参数获取输入。


不错的提交。我用2条额外的输入/输出线更新了挑战。同样,不需要严格的I / O。
arminb

@arminb谢谢!那样的话,明天我可以缩短很多时间。
Οurous

@arminb我已经更新了它,因此它在新情况下应该有效。如果我使用的I / O不可接受,我会在早上再次进行修改。
世纪

0

Perl,40个字节

Inludes +1a

perl -aE 'say/$/*grep${$.}{$_*$`|1}^=1,@F for-1,1' <<< "7 8 100 101 222 223"

输出不排序。

假定为正页码(尤其是no page 0)。假设丢失的页面仅被提及一次。不在乎输入是否已订购。

每次运行仅处理一本书,可节省以下3字节37

perl -aE 'say/$/*grep$z{$_*$`|1}^=1,@F for-1,1' <<< "7 8 100 101 222 223"
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.