Показать счет (в разных базах)


16

Tallying - это простая система подсчета, которая работает на базе 5. В мире существуют различные системы подсчета, но в большинстве англоязычных стран, пожалуй, самая простая - подсчитывать единицы измерения, отмечая вертикальные линии, а затем каждая пятая отметка ставит горизонтальную линию через предыдущую коллекцию из четырех. Это объединяет метки в группы по 5 (и их легче быстро подсчитать).

Вы собираетесь написать программу, которая отображает метки до заданного значения. Но подсчет только в базе 5 скучно! Следовательно, ваша программа также должна отображать результаты в разных базах.

вход

Входными данными будут одно или два неотрицательных целочисленных значения, разделенных запятой (например, 9или 8,4). Первое число - это значение, которое должно отображаться в подсчете. Второе значение является основой подсчета. Если второе значение не указано, используйте базу 5 .

Выход

Выходными данными будет введенное значение, представленное в виде художественных меток ASCII. Вот несколько примеров, с которыми вы можете протестировать свою программу - ваши результаты должны точно соответствовать им!

Вход: 12или12,5

 | | | |   | | | |   | |
-+-+-+-+- -+-+-+-+-  | |
 | | | |   | | | |   | |

Входные данные: 7,3

 | |   | |   |
-+-+- -+-+-  |
 | |   | |   |

Входные данные: 4,2

 |   |
-+- -+-
 |   |

Ввод: 6,1или 6,10(обратите внимание на начальные пробелы)

 | | | | | |
 | | | | | |
 | | | | | |

Также обратите внимание, что основание 1 должно быть непоследовательным - следует использовать только вертикальные линии.

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

правила

  • Это , поэтому выигрывает самая короткая правильная реализация (в байтах).
  • Ввод / вывод может быть на любом подходящем носителе (например, stdin / stdout, file ...).
  • Ввод может быть в форме нескольких аргументов командной строки или разделенных пробелами и т. Д., Если он больше подходит для вашего целевого языка.
  • Конечные переводы строк разрешены в выходных данных. Конечные пробелы не являются. Это правило применяется только тогда, когда есть выход (т.е. не когда введенное значение равно 0).
  • Ваш код должен по умолчанию использовать базу 5, если база не введена.

3
Не должен ли вывод 6,1выглядеть больше как -+- -+- -+- -+- -+- -+-?
Питер Тейлор

3
Если вы укажете «Входные данные будут состоять из одного или двух положительных целых значений, разделенных запятой (например, 9 или 8,4)». тогда мы сможем принять это как данность и не беспокоиться о том, что «ваша программа должна быть надежной - вы должны проверить вводные данные ...», помимо обработки одного или двух чисел.
AndoDaan

1
@PeterTaylor -+-будет представлять два, потому что есть вертикальная линия и горизонтальная оценка через нее. База 1 будет иметь только вертикальные линии. @AndoDaan исправлено.
Шон Лэтэм

Хорошо --- --- --- --- --- ---тогда Для согласованности с другими основаниями вы должны наносить горизонтальный удар по b-1вертикальным линиям. Если он предназначен для непоследовательности, вы должны заявить об этом явно.
Питер Тейлор

Я сделал это. Извините, я думал, что это подразумевается.
Шон Лэтэм

Ответы:


4

CJam 103 85 72 символа

Попробуйте это на http://cjam.aditsu.net/ .

оригинал

q","/(i:A\_,{~i}{;5}?:B_@*{(_{" |"*S"l"++AB/*AB%}{;MA}?\:J" |l""-+ "er\" |"*N+_J\+@2$+@J\+++"l"Ser}{;}?

Работает, определяя один набор чисел с пробелами, линиями и l для пробелов, которые должны оставаться пробелами. Затем использует функцию er (транслитерации) для создания второй строки. Наиболее неэффективная часть имеет дело с 1 и 0 частными случаями. Буду редактировать как я его улучшу. Совет Мне потребовалось слишком много времени, чтобы понять: поскольку второй вход, равный 1, равен бесконечности или первому входу +1, переопределение его, когда оно равно 1, экономит много работы.

наиболее улучшенный до сих пор с запятой

l",":G/(i:A\_5a?~i:B_@*{(_" |":K*\{SG++AB/*AB%}{A}?\_KG+"-+ "er[\GSer_@@M]\K*N+*}{;}?

наиболее улучшенный до сих пор с вводом через пробел

Естественно, CJam действительно предназначен для ввода с разделителями. Размещение ввода в 20 3 вместо 20,3 является огромным преимуществом.

ri:Aq_5s?S-i(_)A)?:B*{B(" |":K*STs++ABmd@@*_K"-+"er[\_@@M]\K*N+*TsSer}M?

5

Python 2 - 111 108 119 144 140 136 135 134 - Попробуйте

Хорошо, давайте попробуем:

i=input()
n,b=[(i,5),i][i>[]]
o=b-1
a=[n,n%b][b>1]*' |'
m=(b>1)*n/b
s=(' |'*o+'  ')*m+a
print(s+'\n'+('-+'*o+'- ')*m+a+'\n'+s)*(b*n>0)

Изменить: я упустил из виду, что не должно быть никакого вывода, если n==0или b==0. Это стоит мне 11 символов. :(

Изменить: Хорошо, после исправления второй проблемы, упомянутой в комментариях, мое решение в основном сходится с решением от BeetDemGuise.


Это печатает новые строки, когда любой из входов (или оба) равен нулю, что в соответствии с задачей нежелательно. Кроме того, что если в программу введен только один номер?
BeetDemGuise

1
Это терпит неудачу, когда второе значение опущено ( bдолжно быть 5 в этом случае). Я сделаю это более ясным в вопросе. Изменить: о, неважно, вы исправили это так же, как я сделал этот комментарий!
Шон Лэтэм

Какой это Python?
бета-распад

Это Python 2.7.8. - О, в самом конце произошла крошечная ошибка ...
Фалько

1
Если это Python 2.x, не могли бы вы сохранить еще один символ, используя n/bвместо n//b?
Эмиль

5

Bash, 239 228 199 189 188

Вот моя попытка, это может быть много в гольфе.

Примечание: вторая строка не вычитает 5 из 2, она устанавливает значение по умолчанию, если $2оно пустое!

n=$1
b=${2-5}
((n<1&b<1))&&exit
while ((n>b&b>1));do
n=$[n-b]
x+=\
y+=-
for i in `seq $[b-1]`;{
x+='| '
y+=+-
}
x+=\
y+=\
done
for j in `seq $n`;{
x+=' |'
y+=' |'
}
echo -e "$x\n$y\n$x"

Работает {1..$n}вместо `seq $n`?
FUZxxl

@FUZxxl, к сожалению, нет, h=8;echo {1..$h}выходы{1..8}

Это не хорошо.
FUZxxl

3

Питон - 171 143

i=input();t,b=i if[0]<i else(i,5);b=[b,t+1][b==1];l,d,m,o=' |',t/b,t%b,b-1;r=(l*o+'  ')*d+l*m
if t*b>0:print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

Программа довольно проста:

  • Получите вход и попробуйте распаковать в t,b. Если это не помогло, просто назначьте правильные значения.
  • Если база была 1, измените ее значение на то, что может легко обрабатывать все вертикальные линии ( t+1).
  • Установите некоторые переменные и создайте нижнюю и верхнюю части списка.
  • Распечатайте подсчеты, если оба tи bне равны нулю.

РЕДАКТИРОВАТЬ 1: Используйте inputфункцию, а не raw_inputпосле некоторой игры.

РЕДАКТИРОВАТЬ 2: Спасибо Falko за указание на небольшую ошибку с моей ненулевой проверкой. Теперь наш код в основном идентичен, за исключением некоторых имен переменных и небольшой логики.

РЕДАКТИРОВАТЬ 3: Благодаря тому, как Python сравнивает последовательности и различные типы , мы можем сравнить iс, listчтобы получить более короткую версию нашего try...exceptблока.

Вот негольфированная версия:

i=input()

# If True, `i` must be a list
if [0]<i:
    t,b=i
# Otherwise, we know its a number (since `list` comes after `int` lexicographically.)
else:
    b=5
    t=i

b = b if b==1 else t+1
l=' |'
d=t/b
m=t%b
o=b-1

r=(l*o+'  ')*d+l*m
if t and b:
    print r,'\n',('-+'*o+'- ')*d+l*m,'\n',r

я думаю t&b это Falseза 10,5. В противном случае наши решения сходятся! ;)
Фалько

@ Фалько Вы правы в обоих случаях! Вы знаете, что они говорят о великих умах.
BeetDemGuise

Было бы здорово, если бы мы могли найти короткий способ проверить, iявляется ли скаляр или список. Тогда мы могли бы броситьtry ... except монстра.
Фалько

@ Фалько Я думаю, что нашел чек на 1 байт лучше. A listвсегда больше, чем int. Кроме того, lists сравниваются в лексикографическом порядке. Так что, если мы сравним [0]<iэто всегда вернется, Falseеслиi это число, а Trueесли iэто список (с ненулевым первым элементом).
BeetDemGuise

1
Большой! Я еще больше сократил ваш подход. Хорошая командная работа! :)
Фалько

3

Ява, 343

class C{public static void main(String[]a){long n=new Long(a[0])+1,b=a.length>1?new Long(a[1]):5;if(b>0){if(b<2)b=(int)2e9;int i;for(i=1;i<n;i++)p(i%b>0?" |":"  ");p("\n");for(i=1;i<n-n%b;i++)p(i%b>0?"-+":"- ");if(n>b)p("- ");for(i=1;i<n%b;i++)p(" |");p("\n");for(i=1;i<n;i++)p(i%b>0?" |":"  ");}}static void p(String s){System.out.print(s);}}

Меньше гольфа:

class C {
  public static void main(String[] a) {
    long n=new Long(a[0])+1, b=a.length>1 ? new Long(a[1]) : 5;
    if(b>0) {
      if(b<2) b=(int)2e9; // if the base is 1, pretend the base is 2 billion
      int i;
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
      p("\n");
      for(i=1;i<n-n%b;i++) p(i%b>0 ? "-+" : "- ");
      if(n>b) p("- ");
      for(i=1;i<n%b;i++) p(" |");
      p("\n");
      for(i=1;i<n;i++) p(i%b>0 ? " |" : "  ");
    }
  }
  static void p(String s) {
    System.out.print(s);
  }
}

Вы можете сэкономить несколько сделав , поэтому вам не придется объявить его отдельно. Еще несколько, делая в своих циклах вместо того, чтобы увеличивать его отдельно (и в третьем цикле). Еще один с помощью . ilongi++%b>0i++<n%bb=b<2?(int)2e9:b
Geobits

3

Perl - 167 165 156

my($n,$b)=($ARGV[0]=~/(\d+)(?:,(\d+))?/,5);print$b>1?map{join(" ",($_ x($b-1))x int($1/$b)," | "x($1%$b))."\n"}(" | ","-+-"," | "):join" ",("---")x$1if$1*$b

ungolfed

my($n,$b) = ($ARGV[0] =~ /(\d+)(?:,(\d+))?/, 5);
print($b>1 ?
    map{ 
        join(" ",($_ x ($b-1)) x int($1/$b)," | " x ($1%$b))."\n"
    } (" | ","-+-"," | ") :
    join " ", ("---") x $1
) if $1 * $b

отображает горизонтальные линии вместо вертикальных для базы 1 :(
китайский Perl Goth

@chineseperlgoth да, это одно из требований. Пожалуйста, прочитайте комментарии Q.
Фози

3

С - 193

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

Конечно, очень некрасивые определения всегда помогают :)

Количество символов включает только необходимые пробелы и новые строки.

#define P printf(
#define L P" |")
#define A P"\n");for(i=0;i<a;)b==1?i++,L:i++&&i%b==0?P
i;
main(a,b)
{
    scanf("%d,%d",&a,&b)<2?b=5:!b?a=0:a;
    if(a){
    A"  "):L;
    A"- "):a%b&&i>a/b*b?L:P"-+");
    A"  "):L;}
}

Ваш код, кажется, печатает новые строки, когда одно из значений равно нулю. Это явно запрещено. Ваше решение не соответствует.
FUZxxl

@FUZxxl Вы правы, я пропустил это! Это плохое быстрое решение придется сделать сейчас. Надеюсь, у меня скоро будет время, чтобы найти лучший путь.
Allbeert

Я уверен , вы можете сохранить несколько символов путем замены printfс puts, и заменой returnс тройным оператором.
Миллинон

@millinon Проблема в putsтом, что он добавляет новую строку каждый раз :(. А для троичного оператора невозможно добавить returns или fors внутри них!. Ваш комментарий дал мне идею сохранить еще несколько символов очень легко удалив, returnхотя. Спасибо!
Allbeert

2

C # 271 байт

Не самое короткое, я не смог обработать входные данные, потому что ему нужно было принять 0 в качестве входных данных.

using C=System.Console;class P{static void Main(){var L=C.ReadLine().Split(',');int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")f+=f<2?t:0;}}

Форматированный код:

using C=System.Console;

class P
{
    static void Main()
    {
        var L=C.ReadLine().Split(',');
        int t=int.Parse(L[0]),f=L.Length>1?int.Parse(L[1]):5,r=3,i;

        for(var R="";t*f>0&r-->0;C.WriteLine(R.TrimEnd()))
            for(R="",i=0;i<t;R+=r==1&i++<t-t%f?(i%f<1?"- ":"-|"):i%f<1?"  ":" |")
                f+=f<2?t:0;
    }
}

1

Lua - 219 203 байта

Я пошел для изготовления d копий b копий "|", затем добавил r копий "|" в конце. Я чувствую, что, возможно, мне следовало бы идти с «подсчетом» на «|» в строке по одному.

l=' |'s=string.rep _,_,a,b=io.read():find'(%d+)%D*(%d*)'b=tonumber(b)or 5 d=(a-a%b)/b f=b>1 and s(s(l,b-1)..'  ',d)g=b>1 and s(s('-+',b-1)..'- ',d)r=b>1 and a%b or a e=s(l,r)..'\n'print(f..e..g..e..f..e)

ungolfed:

l=' |'          --the base string
s=string.rep    --string.rep will be used a lot, so best shorten it

_,_,a,b=io.read():find'(%d+)%D*(%d*)' --reads a,b I'm probably way of the mark with this one

b=tonumber(b)or 5

d=(a-a%b)/b -- shorter than math.floor(a/b), d equal the vertical mark

f=b>1 and s(s(l,b-1)..'  ',d) or '' --creates d multiples of b multiples of "|" more or less
g=b>1 and s(s('-+',b-1)..'- ',d)or''--same as above but with the middle "-+-"

r=b>1 and a%b or a --idk maybe i should set r before d(a- a%b )/b

e=s(l,r)..'\n'  -- makes the remainder string, notice that if b==1  then e will output all the "|" 

print(f..e..g..e..f..e) -- here's where the real magic happens!

Образец:

c:\Programming\AnarchyGolfMine>lua test.lua
13,5
 | | | |   | | | |   | | |
-+-+-+-+- -+-+-+-+-  | | |
 | | | |   | | | |   | | |


c:\Programming\AnarchyGolfMine>lua test.lua
6,2
 |   |   |
-+- -+- -+-
 |   |   |


c:\Programming\AnarchyGolfMine>lua test.lua
18,1
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | |

1
Не могли бы вы опубликовать чуть более читабельную и негольфированную версию? Гольф в Луа выглядит интересно!

@ Алессандро готово. И спасибо, это заставило найти пару вещей, которые я пропустил.
AndoDaan

1

JavaScript (193)

Это может быть слишком сложно.

s=prompt().split(",");a=+s[0];b=s[1];b=b?+b:5;o=b>1;v=" | ";q=w="";for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")for(i=o;c&&i<b;i++)c--,q+=v,w+=g&&o?"-+-":v;if(a&&b)console.log(q+'\n'+w+'\n'+q)

Комментируемая версия

s=prompt().split(",");
a=+s[0];
b=s[1];
b=b?+b:5;   // convert b to int and default to 5
o=b>1;      // special handling for b0 and b1
v=" | ";
q=w="";
// calculate number of lines and number of groups
for(g=~~(a/b),c=o?a-g:a;g+1;g--,q+=" ",w+=" ")
    for(i=o;c&&i<b;i++)
        c--,  // decrease line count
        q+=v,
        w+=g&&o?"-+-":v; // use " | " for last group and "-+-" for others
if(a&&b) // handle b0
    console.log(q+'\n'+w+'\n'+q)

1

Питон - 127 123 122

Просто крадусь с немного более короткой версией Python.

edit: исправлено 0 не печатать ничего и rejigger, в конечном итоге одинаковой длины

k=input()
k=i,j=((k,5),k)[k>[]]
for m in[' |','-+',' |']*all(k):
 print(m*(j-1)+m[0]+' ')*(i/j*(j>1))+' |'*(i%(j+(j<2)*i))

0

C (207 символов)

Новая строка справа exitпредназначена только для разборчивости.

#define P printf(
#define t(v)for(a=c;b<=a;a-=b)a-c&&P" "),P v+1),q(b,v);q(a," |");P"\n");
q(n,c){while(n--)P c);}a;b;c;main(){scanf("%d,%d",&c,&b)<2?b=5:0;b&&c||
exit();b==1?b=32767:0;t("| ")t("+-")t("| ")}

scanfИспользование бесстыдно украдено у Allbeert. Обратите внимание, что это решение не компилируется с gcc, поскольку оно пытается применить несуществующий прототип для exit. Компилировать с работающим компилятором C, какtcc . Кроме того, эта функция может работать или не работать на 64-битных платформах. Используйте с осторожностью.

Вот оригинальная реализация ungolfed, на которой это основано:

#include <stdio.h>
#include <stdlib.h>

static void
tally_line(int base, int count, const char *str)
{
     int follower = 0, i;

     /* full tallies first */
     for (; count >= base; count -= base) {
          if (follower++)
               putchar(' ');

          /* only print second character */
          printf(str + 1);

          for (i = 0; i < base; i++)
               printf(str);
     }

     /* partial tally */
     for (i = 0; i < count; i++)
          printf(" |");

     /* newline */
     puts("");
}

extern int
main(int argc, char **argv)
{
     int base, count;

     /* do away with program name */
     count = atoi(*++argv);

     base = argc - 3 ? 5 : atoi(*++argv);

     /* remove 0 later */
     base | count || exit(0);

     /* a crossed-out tally never appears for large numbers */
     if (base == 1)
          base = 32767;

     tally_line(base, count, "| ");
     tally_line(base, count, "+-");
     tally_line(base, count, "| ");

     return (EXIT_SUCCESS);
}

0

Python 2 , 134 126 123 114 байтов

lambda i,j=5,a=" |":"\n".join(("",(a*~-j+"  ","-+"*~-j+"- ")[x%2]*(i/j))[j>1]+a*(i,i%j)[j>1]for x in(0,1,2)if i*j)

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

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

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