7 л8р чем 9? (Семь позже девяти?)

10

Это довольно простой код для игры в гольф. Ваша программа, учитывая строку ASCII, должна разбить эту строку на две строки, которые она будет оценивать. Если вторая строка «позже», чем первая, она вернет 1, если она «раньше», чем первая, вернет -1, а если они одинаковые, вернет 0. В уточнить, что означают «позже» и «раньше», давайте рассмотрим коды символов ASCII. Вам нужно сравнить каждый символ строки, рассматривая каждый из них как цифры числа. Позже относится к большему числу, встречающемуся после меньшего числа. Строки будут отформатированы с дефисом для разделения двух групп ввода.

Посмотрите на этот пример:

7-9как вход должен вернуться 1.

7преобразует в код ASCII 55и 9преобразует в код ASCII 57.

Как 57происходит численно после 55, 9позже 7.

Другой пример:

LKzb-LKaj как вход должен вернуть -1

Последовательности кода ASCII для этого 76-75-122-98и76-75-97-106

Это задача для игры в гольф, и количество байтов определяет, как будут оцениваться записи.

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

Удачи!

РЕДАКТИРОВАТЬ: Чтобы быть более ясным, каждый символ должен рассматриваться как цифра в числе. В этом примере LKzb-LKaj, хотя jпозже b, позже , zпозже a, и поскольку это более значимая цифра, она имеет приоритет. Предоставленная строка всегда будет содержать не менее 3 символов, что исключает пустые строки из сферы этой проблемы.

РЕДАКТИРОВАТЬ: Вот еще несколько тестов, для вашей помощи:

  • A-9 -> -1
  • 11-Z -> -1
  • 3h~J*-3h~J* -> 0
  • Xv-Y0 -> 1
Сэм Уивер
источник
1
Две строки гарантированно имеют одинаковую длину?
es1024
5
Тестовый пример 11-Z-> -1не имеет смысла, учитывая текущую формулировку вопроса. Z(90) больше 1(49) и является наиболее значимой буквой. Пожалуйста, уточните, как сравниваются строки разной длины.
Джордж Райт
2
А как насчет A-AA?
2
@ SamWeaver Я знаю, что самая левая цифра - самая значимая цифра, поэтому я не понимаю, почему 11>Zв ваших примерах, когда 1<Z. Должно быть какое-то неопределенное поведение для строк разной длины, или пример неправильный.
Джордж Райт
3
Как объяснено ранее: каждая строка должна рассматриваться как цифра в числе base-127. Если бы вы рассчитывали в этой системе, вы бы начали с символа, увеличивали его до барьера печатаемых символов, ~равным 126, затем увеличивали бы следующую цифру на единицу, возвращая начальную цифру в !. Каждое увеличение самой значимой цифры эквивалентно увеличению второй самой значимой цифры на 127.
Сэм Уивер

Ответы:

11

Pyth - 11 байт

Легко, использует ._знак, чтобы получить знак и Cполучить коды символов.

._-F_CMcz\-

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

Тестовый пакет .

._               Sign of number
 -F              Fold subtraction (this finds difference of a tuple)
  _              Reverse list to get correct order of operands when subtracting
   CM            Map char, already treats strings as digits of base256 number
    c \-         Split by "-"
     z           Input
Maltysen
источник
Очень хорошо! Выполняет, как ожидалось.
Сэм Уивер
7

CJam, 12 байт

l'-/esfb~\-g

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

l   e# Read a line from STDIN.
'-/ e# Split it at spaces.
es  e# Push the current time (milliseconds since epoch).
fb  e# Consider each string as digits in base huge-number.
~\  e# Dump the results and reverse their order.
-g  e# Subtract and apply sign function.
Деннис
источник
Отлично! Это проходит все тестовые случаи.
Сэм Уивер
6

Ява, 86 118

int f(String...s){return(int)Math.signum((s=s[0].split("-"))[1].compareTo(s[0])*(s[0].length()==s[1].length()?1:-1));}  

Очень странный способ сравнения строк. Сделано быстрое исправление, чтобы он прошел дополнительные тестовые случаи, позже будет искать больше гольфизма.

Спасибо Вартану в комментариях за signumпредложение

Geobits
источник
Разве сравнение Java не возвращает 1,0, -1 в любом случае? Я знаю, что это не гарантировано, но есть ли это? в этом случаеreturn s[0].compareTo(s[1]);
Вартан
Это хорошо, но он не проходит тестовый случай 11-Zвозврата -1, он возвращается 1.
Сэм Уивер
Ах, это не было ясно до того, как были добавлены эти тесты. Исправлена.
Geobits
@Vartan Нет, он возвращает разницу в значении в первой несовпадающей позиции (или разницу в длине, если совпадают все символы). Например, "A".compareTo("Z") возвращает-25 . К несчастью.
Geobits
Можете ли вы объяснить эту строку? i = a!=b ? b-a : s[1].compareTo(s[0]);Кажется, я не понимаю ... Кроме того, вы можете использовать Math.signum и сохранить себя, объявив i;
Вартан
4

Perl, 31 байт

#!/usr/bin/perl -p
/-/;$_=($`.$'^$`)cmp($'.$`^$')

30 байт + 1 байт для -p. Принимает ввод на STDIN.

объяснение

Когда операнды cmpимеют разную длину, например, chickenи egg, они выравниваются так:

c  h  i  c  k  e  n
e  g  g  \0 \0 \0 \0

так что egg> chicken( \0это нулевой байт). Но мы хотим, чтобы они были выровнены так:

c  h  i  c  k  e  n
\0 \0 \0 \0 e  g  g

так что chicken> egg.

Для этого мы объединяем их, один раз с chickenдо eggи один раз с eggперед chicken:

c  h  i  c  k  e  n  e  g  g
e  g  g  c  h  i  c  k  e  n

Теперь, когда две наши строки имеют одинаковую длину, мы удаляем ведущее слово, используя XOR для получения:

\0 \0 \0 \0 \0 \0 \0 e  g  g
\0 \0 \0 c  h  i  c  k  e  n

И теперь мы можем использовать, cmpчтобы найти то, что было первым. (Там я это сказал!)

ThisSuitIsBlackNot
источник
Очень умно - Браво!
Сэм Уивер
3

Python 2, 88 символов

a=raw_input().split('-');print-cmp(*(map(ord,s.rjust(max(map(len,a)),'\0'))for s in a))

cmpне работает правильно, когда у вас есть две строки разной длины, поэтому я должен дополнить их обоими нулевым символом (который ordпреобразуется в 0) для обработки этого случая. К сожалению, это добавило около 35 символов, плюс теперь это две строки вместо одной, потому что мне нужна длина ввода и его перебор.

Алекс Ван Лью
источник
К сожалению, это неверное решение. Следующий тест: 1-2, который должен возвращать 1возвращается -1. Умная работа, хотя.
Сэм Уивер
К сожалению, кажется, что операнды поменялись местами. Это супер странно, я проверил это с парой ваших тестовых случаев, и я думал, что это работало отлично! Неважно, я могу изменить его без изменения количества символов. Дайте ему шанс сейчас.
Алекс Ван Лью
Ваше редактирование исправило этот случай, но теперь оно не соответствует 11-Aслучаю, который должен вернуться -1, а не возвращаться 1в этом примере.
Сэм Уивер
Мне не нравятся твои правила длины. Я исправил это по цене около 35 символов, и я не думаю, что смог бы сделать это лучше.
Алекс Ван Лью
1
Мне удалось получить более короткий ответ, чем ваш, кодировав строку в шестнадцатеричный формат, а затем проанализировав эту строку как int. В Python 2 для этого, по-видимому, по умолчанию используется значение big-endianness. Таким образом, заполнение 0 больше не требуется.
Дюны
2

R, 54 байта

Это требует библиотеки пракмы. Он разбивает входную строку на -. Право оправдывает строки. Занимает их и делает различий.

Таким образом, для 11-7 мы получаем строки «11» и «7». Их ранг [2, 1]. Разница -1. Для 3h ~ J * -3h ~ J * мы получаем "3h ~ J *" и "3h ~ J *". Ранг этих [1.5, 1.5] с diff 0.

diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))

Тестовые примеры

> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: LKzb-LKaj
3: 
Read 2 items
[1] -1
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: A-9
3: 
Read 2 items
[1] -1
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: 11-Z
3: 
Read 2 items
[1] -1
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: 3h~J*-3h~J*
3: 
Read 2 items
[1] 0
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: Xv-Y0
3: 
Read 2 items
[1] 1
MickyT
источник
Умная. Хорошая работа :)
Алекс А.
2

CoffeeScript, 143 140 139

f=(s)->[a,b]=((t=s.split '-').map (y)->Array((m=Math.max) 1, 1+(m ((l=(c)->c.length) t[0]),l t[1])-l y).join('\u0000')+y);`b<a?-1:(b>a?1:0)`

Вот jsfiddle с результатами (смотрите в консоли)

danielrw7
источник
2

PERL, 46 36 байт

print$2cmp$1if"@ARGV"=~/(\S+)-(\S+)/

Преобразует список argv в строку, разбивает дефисом на arg слева и справа без пробелов, а затем возвращает вызов cmp.

Эрик
источник
Я подозреваю, что вы можете избавиться от ряда пробелов и;
MickyT
Должен быть в состоянии сойти с рук: "@ARGV"=~/-/;print$`cmp$' (непроверенный)
Jarmex
1
Хорошая идея для использования cmp, но она не работает, когда длина строки отличается. "A" cmp "9"равен 1, а "11" cmp "Z"равен -1, хотя оба входа должны возвращать одно и то же значение для этой задачи.
ThisSuitIsBlackNot
1

Python 3, 84 байта

x,y=[int.from_bytes(i.encode(),"big")for i in input().split("-")];print((x<y)-(y<x))

Разделить строку ввода по "-" . Преобразуйте строки Unicode в строки байтов, затем интерпретируйте эти строки байтов как целые числа с прямым порядком байтов. Наконец сделайте сравнение - (не) к счастьюcmp ) больше не доступно в Python 3.

Python 2, 69 байт

print -cmp(*[int(i.encode("hex"),16)for i in raw_input().split("-")]) 
Дюны
источник
Вы можете сбрить персонажа, убрав пробел между printи cmp.
Алекс Ван Лью
1

Python 2, 79 байт

Довольно простое решение, и его легко понять. Сравнивает длины строк, затем сравнивает строки лексографически.

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

s,t=raw_input().split('-')
x,y=len(s),len(t)
print(x<y)*2-1if x-y else cmp(t,s)
mbomb007
источник
1

perl5, 64

perl -aF- -pe '@f=map{length}@F;$_=$f[1]<=>$f[0]||$F[1]cmp$F[0]'

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

perl -laF- -pe '@f=map{length}@F;$_=$f[1]<=>$f[0]||$F[1]cmp$F[0]'

Эта более длинная версия правильно обрабатывает несоответствующие длины.

hildred
источник
/-/,$_=$`cmp$'было бы проще, и вы можете пропустить -aF-бит. Кроме того, я считаю это 20 (16 для $_=$F[1]cmp$F[0]и 4 для paF-, сохраненные в файл и запустить как perl -paF- file.pl).
Примо
1
Как я заметил в ответе Эрика , cmpон не работает, когда две строки имеют разную длину, например, с 11-Z.
ThisSuitIsBlackNot
@ThisSuitIsBlackNot, исправлено.
Hildred
Ницца. Вы можете сыграть в гольф до 39 с /-/;$_=length$'<=>length$`||$' cmp$`и -p. ( $`сохраняет все до совпадения с регулярным выражением, $'сохраняет все после.) Использование на mapсамом деле стоит больше байтов, чем просто вызов lengthдважды.
ThisSuitIsBlackNot
0

F #, 53

fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a

Это в форме анонимной функции (лямбда), поэтому вы должны вставить ее и предоставить параметр сразу после is (или, используя обозначение трубопровода). Например (в FSI):

> "7-9" |> fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a
1
> "abc-abc" |> fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a
0
> "LKzb-LKaj" |> fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a
-1
Jwosty
источник
0

JavaScript ES6, 46 43 байта

f=s=>((a=s.split('-'))[1]>a[0])-(a[1]<a[0])
Джордж Райт
источник
Хорошая работа, но это не завершает тестовый пример 2: 11-Zдолжен вернуться, -1но он возвращается 1.
Сэм Уивер
1
@SamWeaver Действительно, это было добавлено после ответа и нарушает другие ответы. Можете ли вы объяснить, почему, '11'>'Z'когда '11'<'ZZ'в вопросе нет ничего о том, как сравнивать строку разной длины или какое значение имеет пустая строка?
Джордж Райт
Цель вопроса никогда не менялась, я только добавил эти контрольные примеры и пояснения, потому что понял, что вначале я был недостаточно ясен. Вы правы в том, что я никогда не определял значение пустой строки, и я обновлю вопрос соответствующим образом. Эти контрольные примеры не изменили поведение или цель вопроса, а лишь прояснили его. В примерах вы назвали функцию как таковую, поскольку каждый символ должен рассматриваться как отдельная «цифра» в числе, основание которого эквивалентно всем печатным символам ASCII. Эта механика вопроса никогда не менялась, просто становилась понятнее.
Сэм Уивер
1
@SamWeaver Изменение от неопределенного поведения к определенному меняет его. Ничто не персонаж. Если это не нулевой символ, который это обрабатывает.
Джордж Райт
0

Рубин, 59 байт

a,b=gets.chomp.split ?-
p (b.size<=>a.size).nonzero?||b<=>a
daniero
источник
0

05AB1E , 12 11 9 байт

'-¡₄ö¥0.S

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

'-¡          # Split the (implicit) input on '-'
             #  i.e. 'LKzb-LKaj' → ['LKzb','LKaj']
   ₄ö        # Convert both parts to a Base-1000 number
             #  i.e. ['LKzb','LKaj'] → [21020061037,21020036045]
     ¥       # Push the deltas (subtraction between each sub sequential pair) of the list
             #  i.e. [21020061037,21020036045] → [-24992]
      0.S    # Get the sign [1 for a>0; -1 for a<0; 0 for a==0] (and output implicitly)
             #  i.e. [-24992] → [-1]
Кевин Круйссен
источник