Две дороги разошлись в желтом лесу (часть 2)


25

Это вторая в серии, третья - это две дороги, расходящиеся в желтом лесу (часть 3)

Это основано на двух дорогах, раскинувшихся в желтом лесу (часть 1) , моей предыдущей проблеме. Это было довольно хорошо получено, но это также было довольно тривиально (Java-ответ в 52 байта!), Поэтому я сделал что-то более сложное ...

Вдохновение

Эта задача вдохновлена ​​знаменитым стихотворением Роберта Фроста «Дорога не пройдена»:

Две дороги расходились в желтом лесу,
И извините, я не мог путешествовать обоими
И быть одним путешественником, долго я стоял
И смотрел вниз на одну так далеко, как мог,
На то, где оно согнулось в подлеске;

... 2 абзаца обрезаны ...

Я расскажу это со вздохом
Где-то через века и века:
две дороги расходились в лесу, и я…
я выбрал ту, по которой меньше путешествовал,
И это имело все значение.

Обратите внимание на вторую и последнюю строку I took the one less traveled by,. Ваша цель состоит в том, чтобы найти путь, который наименее пройден в вашей строке ввода. Вы должны вывести одно из двух значений, отличных друг от друга, которые сигнализируют, в какую сторону вам следует повернуть, чтобы выбрать менее пройденный путь. Как только дорога разветвляется (след шестиугольников меняется на число), вы находитесь на перекрестке. Оттуда будут 2 пути, состоящие из цифр. Путь, чьи цифры имеют наименьшую сумму, будет дорогой, не взятой. Обратите внимание, что у дороги, которая не выбрана, может быть больший путь, но меньшая сумма пути. Вот несколько примеров / тестовых примеров из программы, которая печатает «влево» или «вправо» для пути, не принятого:

 1     2
  1   2
   1 2
    #
    #
    #
left (3 < 6)


 1     2
  2   2
   1 1
    #
    #
    #
left (4 < 5)


 12    2
  11  2
   1 1
    #
    #
    #
right (6 > 5)


 99   989
  99  89
  99 99
  99 99
    #
    #
    #
   # 
left (72 < 79)


1111 1110
 001 111
  11 11
  11 11
    #
   ##
  ##
 ##  
left (9 < 10) (Note: 1111 is interpreted as 1+1+1+1=4, not 1111=1111)


1       1
 0     1
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)


1   1 
 0   1  
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)

Вещи, чтобы принять и запомнить

  • Там всегда будет 2 пути. Ни больше ни меньше.
  • Вы можете получать входные данные из STDIN по одной строке за раз, строку, содержащую символы LF, или строку, содержащую буквенную обратную косую черту и n. Если вам нужен вклад каким-либо другим способом, попросите одобрения в комментариях.
  • Вам не нужно беспокоиться о неверном вводе или связанных путях. Они никогда не будут введены в вашу программу / функцию.
  • Ввод может быть любой длины по ширине или высоте, меньше строкового ограничения вашего языка.
  • Там никогда не будет #и число в одной строке.
  • Все цифры в пути являются положительными целыми числами от 0 до 9.
  • Ввод или вывод с завершающим переводом строки разрешен.
  • См. Мой ответ JS ES6 ниже для примера.
  • Между двумя путями всегда будет хотя бы 1 пробел.
  • 2 пути всегда будут иметь одинаковую высоту для каждой карты, но могут отличаться на других картах.
  • Если вы не уверены в конкретном тестовом случае, пожалуйста, сообщите мне.
  • 1111 интерпретируется как 1 + 1 + 1 + 1 = 4, а не 1111 = 1111. Карта представляет собой последовательность однозначных чисел, а не чисел произвольной длины.
  • Это , поэтому выигрывает самый короткий ответ в байтах!
  • Стандартные лазейки запрещены

Если у вас есть какие-либо вопросы по поводу этого задания, задавайте их в комментариях, и удачи!


Эй, вы можете увидеть все ответы и их количество байтов, вставив их $("div > h1").map(function(){return $(this).text()}).get().join("\n");в консоль!
programmer5000

1
Вот альтернативная версия с удаленными пробелами и игнорированием зачеркнутых ответовlet answers = $('div > h1').map(function(){return $(this).clone().children(':not(a)').remove().end().text().replace(/\s+/g,' ').trim()}).get();answers.splice(0, 1);answers.join('\n');
Дэвид Арчибальд

2
A # не шестиугольник ...
user253751

1
« но это также было довольно тривиально (Java-ответ в 52 байта!) » теперь 43 байта. ;)
Кевин Круйссен

Еще раз закрыть голосование? Что, черт возьми, не так с вами?
Мэтью Ро

Ответы:


2

05AB1E , 21 15 байт

Выходы 0 для левого и 1 для правого.

|vy#õK€SO})øO`›

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

объяснение

|v                # for each line in input
  y#              # split on spaces
    õK            # remove empty strings
      €S          # split each string into a list of chars
        O         # sum each sublist
         }        # end loop
          )ø      # wrap stack in a list and zip
            O     # sum each sublist (side of the tree)
             `›   # compare left to right

11

Сетчатка , 28 байт

\d
$*
%r`1\G
-
Os`.
+`-1

1+

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

Отпечатки 0слева и 1справа. Предполагается, что на любых строках нет пробелов.

объяснение

\d
$*

Конвертировать каждую цифру Nв ряд N.

%r`1\G
-

По одной в каждой строке ( %), совпадают с последовательными ( \G) из end ( r) и заменяют каждую из них -(то есть превращают правую ветвь в -s).

Os`.

Сортируйте все символы так, чтобы все -s находились прямо перед всеми 1s.

+`-1

Неоднократно отменять пару -и 1.

1+

Попробуйте сопоставить хотя бы один 1(если так, в левом пути было больше весов).



7

Чип , 216 байт

 EZ,Z~.
E~]x-.|
F].>vm'
Ax]}#----------------.
Bx]}#---------------.|z.
Cx]}#------------.,Z|##' E
Dx]}#---------.,Z|`@@('A~^~t
 E.>#------.,Z|`@@-('
A~S`#v--.,Z|`@@-('
*f,--<,Z|`@@-('
e |,Z|`@@-('
,Z|`@@-('
>@@-('
a

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

Немного больше, чем ответ на часть 1 ...

обзор

Chip - это двумерный язык, основанный на реальных схемах, и он работает с компонентными битами каждого байта в потоке байтов.

Это решение сохраняет текущую сумму цифр, которые оно видит, переворачивая знак ввода каждый раз, когда он сталкивается с пробелом, а затем завершается после первого # . Итак, для ввода

 11   12
  2   2
   1 1
    #
    #
    #

Мы получаем 1 + 1 - 1 - 2 + 2 - 2 + 1 - 1 = -1 . Знак результата дается в качестве выходного, отрицательное число дает результат 1, а положительное - 0.

Следовательно, вывод 1означает, что левый путь менее занят, а 0значит - правый.

объяснение

На высоком уровне, вот как это работает:

Основной диагональю с @элементами является аккумулятор, выход которого aопределяется снизу. (Восемь пар@ означает восемь битов, но старший бит - это знак, поэтому это решение может обрабатывать максимальную разницу +127 или -128. Переполнение на полпути нормально, если мы вернемся до завершения.)

Четыре строки, которые начинаются как Ax]}#--..., читают входные данные, а в случае цифры - отрицают ее (при необходимости) и передают значение в сумматоры.

Первые три строки определяют, смотрим ли мы на цифру или последовательность пробелов, и следим за тем, нужно ли отменять цифры.

Остальные элементы, вставленные под входами, и элементы справа, обрабатывают условие завершения и отображают вывод в ASCII (чтобы мы получали символы '0'или '1'вместо значений 0x0или 0x1. Это отображение ASCII не требовало дополнительных байтов, иначе я бы не стал включил это.)


2
Мне нравится, что код выглядит как две расходящиеся дороги.
Лайкони

@Laikoni Я даже не заметил, это круто :)
Phlarx

4

JavaScript (ES6), 55 байт

x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0

Предполагается, что в каждой строке нет завершающих пробелов и выводятся trueдля right, falseдля left. Хитрость заключается в том, чтобы соответствовать каждой цифре на входе, и если после нее есть пробел в той же строке, вычесть ее из общей суммы; иначе добавьте это к общему количеству. Если итоговое итоговое значение меньше 0, то правильный путь - это тот, по которому меньше пройдено, и наоборот.

Попробуйте это:

f=x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = f(this.value)"></textarea>
<div></div>


Вам нужно поставить x=в начале, потому что выражения не допускаются, только функции хранятся как переменные и целые программы.
programmer5000

@ programmer5000 Почему? Кажется немного странным переопределить значения по умолчанию, и это не указывает на то, что это именно тот случай, о котором идет речь.
Wheat Wizard

1
@ programmer5000 На самом деле, неназванные функции разрешены по умолчанию . (Спасибо за фрагмент, кстати)
ETHproductions



2

Сетчатка , 180 байт

Число байтов предполагает кодировку ISO 8859-1.

^(?=( *(0|(1|(?<3>2|(?<3>3|(?<3>4|(?<3>5|(?<3>6|(?<3>7|(?<3>8|(?<3>9))))))))))+.+¶)+)(.+ (0|(?<-3>1|(?<-3>2|(?<-3>3|(?<-3>4|(?<-3>5|(?<-3>6|(?<-3>7|(?<-3>8|(?<-3>9))))))))))+¶)+ *#

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

Я подумал, что я бы также попробовал решение только для регулярных выражений (выше приведено простое регулярное выражение .NET, которое сопоставляет только входы, где должен быть выбран правильный путь, за исключением использования в качестве сокращения для \n).

Это раздражающе повторяется, но это то, что происходит, когда вам приходится обрабатывать каждую возможную цифру индивидуально.

Решение довольно простое приложение балансировочных групп : сначала мы суммируем цифры в левой ветви, помещая Nзахваты в стек 3для каждой цифры N. Затем мы пытаемся достичь #, одновременно извлекая время из стека 3 Nдля каждой цифры Nв правой ветви. Это возможно только в том случае, если сумма цифр в левой ветви больше, чем в правой ветви (поскольку вы не можете выскочить из пустого стека).


Я не знаком с регулярными выражениями .NET, но вы не можете сделать набор символов: [0-9]чтобы соответствовать всем цифрам или \d?
programmer5000

@ programmer5000 Конечно, но тогда я не могу различить их, чтобы определить, сколько снимков мне нужно нажать, чтобы их суммировать.
Мартин Эндер,

2

JavaScript (ES6), 106 104 байта

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

s=b=>(b=b.split("\n"),c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

sэто функция, которая возвращается, trueесли дорога, по которой вы не идете, находится слева. Ungolfed:

var proc = function(str){
    str = str.split("\n");
    var left = 0;
    var right = 0;
    str.forEach(item=>{
        var match = item.match(/\d+/g) || [];
        console.log(match);
        left += +(match[0] ? match[0] : 0);
        right += +(match[1] ? match[1] : 0);
    });
    return left < right;
};

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = s(this.value)"></textarea>
<div></div>


Я надеюсь, что кто-то может получить лучший результат, чем этот ...
programmer5000

Вызов принят @ programmer5000
Дэвид Арчибальд

@DavidArchibald кто-то уже сделал, но я был бы признателен за новый ответ. Вы заинтересованы в третьем в серии ?
programmer5000

конечно. Не понял, что их было 3
Дэвид Арчибальд

2

PowerShell , 80 байт

$args-split'\s|#'-ne''|%{$a+=(($i=[char[]]$_-join'+'|iex),-$i)[($x=!$x)]};$a-gt0

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

(Просто скрипит под питоном ответы.: D)

Выходы True для левого пути и Falseдля правого пути.

Принимает ввод в виде строки, обозначенной линией `n, которая является эквивалентом PowerShell для «строки, содержащей буквенный обратный слеш и n» , или в виде литеральной многострочной строки. Затем мы вводим -splitданные \s(пробелы, включая переводы строки) или #и отфильтровываем все пустые результаты.-ne'' , поэтому у нас остается только массив цифр. Те питаются в петле |%{...}.

На каждой итерации мы сначала берем текущий элемент, приводим $_его в виде charмассива, -joinвместе со знаком плюс +и направляем его к iex(сокращение Invoke-Expressionи аналогично eval). Это сохранено в, $iтак что мы правильно суммируем цифры на этом конкретном фрагменте пути. Затем мы используем это и его отрицательное значение в качестве двух элементов массива ($i, -$i), индексируемых путем перелистывания логического значения взад и вперед. То есть, первую итерацию этого цикла, первый левый фрагмент пути, в который мы будем индексировать -$i; в следующий раз мы возьмем $i; и так далее. Те накапливаются в $aс +=.

Наконец, мы оцениваем, $aявляется ли -gРатер tХаном 0. Если это так, то правый путь имел большую сумму, в противном случае левый путь имел большую сумму. Этот логический результат остается в конвейере, а вывод неявным.


2

CJam , 19 18 байтов

qN/Sf%z{'1*:~:+}/>

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

Отпечатки 0слева и 1справа.

объяснение

q      e# Read all input.
N/     e# Split into lines.
Sf%    e# Split each line around runs of spaces.
z      e# Transpose to group each branch.
       e# Note that each branch will have the same number of digit segments
       e# now but the first branch will also have all the #s at the end in
       e# separate segments.
{      e# For each branch...
  '1*  e#   Join the segments into a single string with 1s as separators.
       e#   This will add the same number of 1s between digit segments in
       e#   both branches (which won't affect their relative sum) and it 
       e#   will also insert a 1 before each # in the first branch.
  :~   e#   Evaluate each character. The digit characters are simply turned
       e#   into their values, but # is the exponentiation operator in CJam.
       e#   This is why we inserted those additional 1s, because 1# is a no-op.
  :+   e#   Sum the digits in the branch.
}/
>      e# Check whether the left branch's sum is greater than the right one's.

1

Mathematica, 80 77 байт

Спасибо Мартину Эндеру за сохранение 3 байта!

#<#2&@@Total@Partition[Tr/@ToExpression[Characters@StringSplit@#/."#"->0],2]&

Чистая функция, принимающая строку с разделителями новой строки в качестве входных данных и возвращающаяся Trueдля перехода по левому пути, Falseчтобы выбрать правильный путь. Будь прокляты те длинные названия команд Mathematica; это как 10 жетонов.


0

Пип , 19 18 байт

LR+XDax:-x+$+$0SGx

Принимает ввод в виде единой строки в командной строке (что потребует цитирования и экранирования строк новой строки, если они выполняются в реальной командной строке). Выходы -1слева, 1справа.Попробуйте онлайн!

объяснение

Перебирает серии цифр, добавляя суммы цифр к подсчету. Знак подсчета меняется каждый раз, в результате чего левые значения являются отрицательными, а правые значения - положительными. Затем мы печатаем знак окончательного подсчета ( -1или 1).

                    a is 1st cmdline arg; XD is regex `\d`; x is "" (implicit)
                    Note that "" in a math context is treated as 0
  +XD               Apply regex + to XD (resulting in `\d+`)
LR   a              Loop over matches of that regex in a:
             $0      Regex match variable containing the full match
           $+        Sum digits by folding on +
      x:-x+          Swap the sign of the tally and add this sum
               SGx  After the loop, print the sign of the tally

0

Haskell , 64 байта

g=sum.map fromEnum
f(a:b:r)|a>"#"=g a-g b+f r|1<3=0
(>0).f.words

Попробуйте онлайн! Использование: анонимная функция (>0).f.wordsпринимает в качестве аргумента строку, разделенную новой строкой, и возвращает Falseвлево и Trueвправо.

Объяснение:

Учитывая вход

 99   989
  99  89
  99 99
    #
    #
   # 

то есть строка " 99 989\n 99 89\n 99 99\n #\n #\n #", а затем wordsудаляет все строки и пробелы и возвращает список оставшихся строк: ["99","989","99","89","99","99","#","#","#"]. Функция fберет первые два элемента aи bиз этого списка и проверяет, aявляется ли строка цифр, сравнивая ее со строкой «#». (Поскольку символ '#'меньше , чем все цифры символов '0', '1'... каждая строка , начинающаяся с цифрой будет лексикографический больше "#".) Функция gотображает каждый символ в строке с его кодом ASCII символов и возвращает их сумму. Когда fмы применяем gк aи bвычисляем g a - g b, это значение левого пути минус значение правого и добавляем его к рекурсивному вызовуfобрабатывать следующие строки. Если левый путь проходит больше, результат отfбудет отрицательным и в противном случае положительным для правильного пути, поэтому (>0)проверяет, будет ли результат больше нуля.


0

Python 3 , 84 байта

Поскольку все текущие представления Python являются функциями, я подумал, что смогу предоставить полную программу.

x=0
try:
 while 1:
  for n in input().split():x=-x+sum(map(int,n))
except:print(x>0)

Печатается, Trueесли левый путь менее пройден, в Falseпротивном случае. Попробуйте онлайн!

Для каждой строки ввода это разбивает пробел, суммирует цифры каждого результирующего элемента и добавляет его к подсчету, переворачивая знак подсчета на каждом шаге. Он продолжает читать строки ввода до тех пор, пока не достигнет строки с символом a #, после чего map(int,n)возникает исключение, и мы выходим из цикла, печатая, Trueесли подсчет является положительным, и в Falseпротивном случае.


0

Пакет, 169 байт

@echo off
set/as=0
:l
set/pr=
if not %r: =%==# call:c - %r%&goto l
cmd/cset/a"s>>9
exit/b
:c
call:r + %3
:r
set/as%1=%2%%10,d=%2/10
if %d% gtr 0 call:r %1 %d%

Отпечатки 0слева, -1справа. Примечание: читает строки до тех пор, пока не найдет строку с символом a #, затем прекратит чтение. Разница в суммах путей ограничена 511 (добавьте 1 байт для поддержки больших различий). Не более 9 цифр в каждой строке каждого пути (поддерживает любое количество строк). Объяснение: dПодпрограмма принимает два параметра: добавлять или вычитать и цифру (ы). Он извлекает последнюю цифру по модулю 10 и оставшиеся цифры делением на 10 и вызывает себя рекурсивно, пока еще остаются цифры. cПодпрограмма принимает три параметра: нужно ли добавить или вычесть, цифры , чтобы добавить или вычесть, и дополнительные цифры , чтобы добавить. Это вызываетdПодпрограмма для обработки добавляемых цифр, а затем для обработки первых двух параметров. Это означает, что вызов cподпрограммы с параметрами-а левая и правая цифры добавят правые цифры и вычтут левые цифры. Наконец, результат сдвигается для извлечения знака.


0

Октава, 46 байт

@(a)diff((a(:)-48)'*(bwlabel(a>35)(:)==1:2))<0

Попробуйте онлайн! Функция, которая принимает двумерный массив символов в aкачестве входных данных.

Объяснение:

a=

    1   1  
     0   1 
      1   1
      1   1
      1   1
      1   1
       1 1 
        #  
        #  
        #  
         # 
          #

a > 35                   %convert the matrix to a binary matrix
                         %where there is a number corresponing
                         %element of the binary matrix is 1.

*   *  
 *   * 
  *   *
  *   *
  *   *
  *   *
   * * 

bwlabel(a>35)            %label each connected component. 


1   2  
 1   2 
  1   2
  1   2
  1   2
  1   2
   1 2 

B=bwlabel(a>35)(:)==1:2  % a binary `[n ,2]` matrix created 
                         % each column related to one of labels

A=(a(:)-48)'             % convert array of characters to array of numbers 

A * B                    % matrix multiplication that computes 
                         % the sum of numbers under each label

diff(A*B)<0              % check if the left is grater than the right

0

Java 7, 219 216 байт

boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

На этот раз бит длиннее 52 байт . ;)
И снова возвращаетсяfalse направо и trueналево.

Объяснение:

boolean c(String s){              // Method with String parameter and boolean return-type
  int l=0, r=0;                   //  Right and left counters
  for(String x : s.split("\n")){  //  Loop over de lines
    l += f(x,0);                  //   Add all left digits to the left-counter
    r += f(x,1);                  //   Add all right digits to the right-counter
  }                               //  End of loop
  return l>r;                     //  Return whether the left-counter is larger than the right-counter
}                                 // End of method

int f(String x, int i){           // Separate method with String and integer parameters, and int return-type
  if(x.contains("#"))             //  If the current line contains "#"
    return 0;                     //   Simply return 0
  int n=0;                        //  Counter
  for(int c :                     //  Loop over the digits by
              x.trim()            //    first removing leading and trailing whitespaces
              .split("\\s+")      //    then split them right in the middle
              [i]                 //    then pick either the left or right side based on the int index parameter
              .getBytes())        //    and convert that String to a byte-array
    n += c-48;                    //   For each of those digit-characters: add it to the counter
                                  //  End of loop (implicit / single-line body)
  return n;                       //  Return the counter
}                                 // End of separate method

Тестовый код:

Попробуй это здесь.

class M{
  boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(" 1     2\n  1   2\n   1 2\n    #\n    #\n    #"));
    System.out.println(m.c(" 1     2\n  2   2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 12    2\n  11  2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 99   989\n  99  89\n  99 99\n  99 99\n    #\n    #\n    #\n   # "));
    System.out.println(m.c("1111 1110\n 001 111\n  11 11\n  11 11\n    #\n   ##\n  ##\n ##  "));
    System.out.println(m.c("1       1\n 0     1\n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
    System.out.println(m.c("1   1 \n 0   1 \n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
  }
}

Выход:

false
false
true
false
false
false
false
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.