Сколько страниц я вырвал?


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 страниц).

Помните, что страница книги всегда имеет переднюю и заднюю стороны. Кроме того, нумерация страниц отличается от книги к книге. Некоторые книги имеют четные номера страниц на левой странице; некоторые на правой странице. Все книги читаются слева направо.

Самый короткий код в байтах побеждает. Строгий формат ввода-вывода не требуется. Ваши программы должны быть в состоянии принять одну или несколько книг в качестве входных данных. Повеселись.


3
Было бы приемлемо, если бы выходные значения не гарантировались для сортировки? (например, 4/5и 5/4)
Арно

Не забудьте обновить задачи, чтобы указать, что порядок вывода должен быть согласованным, либо все, min/maxлибо все max/min. (Хотя лично я предпочел бы, чтобы это не было частью спецификации!)
Shaggy

2
Какова будет причина programs must be able to take one or more books as inputправить? Большинство (если не все) просто обернут код, чтобы проверить одну книгу в цикле или что-то еще. ИМХО, это просто добавляет накладные расходы к ответу практически без выгоды для задачи. На эти вопросы уже получено много ответов, поэтому лучше оставить все как есть, но помните об этом для решения будущих задач.
Род

Похожий тест (любезно @Arnauld): 1,3,5,7,9,11,13,15,17,18- на благо языков, встроенное sortметод лексикографических по умолчанию (при условии , требования последовательно отсортировано будет добавлено в спецификацию).
Лохматый

Ответы:


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 дополнительными линиями ввода / вывода. Также строгий ввод / вывод не требуется.
Армин

Кстати, ваша программа не принимает несколько книг в качестве входных данных.
Армин

@ Emigna Спасибо за хедз-ап. Отредактировал мой ответ соответственно.
Мистер Xcoder

@arminb Теперь это нужно исправить.
Мистер Xcoder

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 дополнительными линиями ввода / вывода. Также строгий ввод / вывод не требуется.
Армин

1
Разве несколько входов за цикл не попадают в строгий ввод-вывод?
Род

1
Можно спорить.
Армин

То, как вы берете книги и их страницы в качестве входных данных, определяется спецификацией ввода / вывода. Требование , чтобы вы действительно взять несколько книг , в качестве входных данных являются частью провокационной спецификации.
Лохматый

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))
  • Первоначально вдохновленный решением Java Оливье и моим собственным (в настоящее время удаленным) решением Japt.
  • 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 прокомментировал пару решений , заявив , что это действительно является обязательным требованием. Я уже прокомментировал проблему с просьбой о ее включении и высказал свое предпочтение против нее - в конце концов, для меня это подпадает под строгий ввод-вывод.
Лохматый

1
Я думаю, что это должно работать на 64 байта. Однако ваш текущий метод сортировки без какого-либо обратного вызова имеет недостатки. Это не удалось бы, например [1,3,5,7,9,11,13,15,17,18].
Арнаулд

Спасибо, @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+
$*

Преобразуйте номера страниц в одинарные.

.+
$&,/$&,

Дублируйте список, вставив a /.

,(?=.*/)
1,

Увеличьте номера страниц в одном экземпляре списка.

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

Подсчитайте количество страниц, но последовательные четные и нечетные числа считаются только одной страницей.

%O`1+

Сортировать счет в порядке.

1+
$.&

Преобразовать счет обратно в десятичную.


Хорошая подача! Я обновил задачу с 2 дополнительными линиями ввода / вывода. Также строгий ввод / вывод не требуется. Кажется, ваша программа на данный момент является единственной, которая проходит все тестовые случаи.
Армин

Не может ,(?=.*/)¶1,быть что-то вроде ,.*/¶1$&этого?
Ven

@ 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 )
Οurous

@ Да, конечно. Также я обновил задачу с 2 дополнительными линиями ввода / вывода. Также строгий ввод / вывод не требуется.
Армин

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 Нет. Я мог бы связать вещи с потоками, но это добавило бы <s> несколько </ s> байтов, а не сохранялось ;-)
Оливье Грегуар

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 дополнительными линиями ввода / вывода. Также строгий ввод / вывод не требуется.
Армин

Я не вижу, где провалились какие-либо ваши тесты. Единственное, что не работает, - это множественные случаи, которые вы добавили спустя много лет после того, как я опубликовал свое решение. В любом случае я обновил решение для обработки нескольких тестов.
Xcali

2

Wolfram Language (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
Вам не нужно SplitBy: Length@Split@⌊#/2⌋&/@{#,#+1}&работает. Но тогда еще короче сделать настил перед картой Length@*Split/@⌊{#,#+1}/2⌋&. И если хотите, вы можете получить тот же счетчик байтов без Юникода:Length@*Split/@{#,#+1}~Floor~2&
Мартин Эндер

Я думаю, что проблема требует строгого формата ввода / вывода.
Эрик Outgolfer

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]

Попробуйте онлайн!

Требования полной программы абсолютно убивают способность Клин конкурировать.

Для тех, кто обращал внимание на мои ответы в Чистом, вы заметите import qualified, что это уродливый хакер, использующий модули, которые не должны использоваться вместе, что необходимо здесь только из-за другого уродливого хака. с GenLibзависимостью Data.Maybeвместо вместо StdMaybe, что является результатом еще одного уродливого хака в библиотеках, переведенных с Haskell Dataдля получения функциональности до того, как собственные библиотеки Clean будут в равной степени завершены.

Принимает ввод через аргументы командной строки.


Хорошая подача. Я обновил задачу с 2 дополнительными линиями ввода / вывода. Также строгий ввод / вывод не требуется.
Армин

@arminb Спасибо! Я смогу сократить это завтра в этом случае.
Οurous

@arminb Я обновил его, поэтому он должен быть действительным для новых случаев. Если ввод-вывод, который я использовал, неприемлем, я пересмотрю его утром.
Οurous

0

Perl, 40 байт

Включает +1в себяa

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

Выход не упорядочен.

Предполагает положительные номера страниц (особенно без страницы 0). Предполагается, что пропущенные страницы упоминаются только один раз. Неважно, заказан вход или нет.

Обработка только одной книги за цикл экономит 3байты для 37:

perl -aE 'say/$/*grep$z{$_*$`|1}^=1,@F for-1,1' <<< "7 8 100 101 222 223"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.