Відображати підсумок (у різних базах)


16

Tallying - це проста система підрахунку, яка працює в базі 5. Існують різні різні системи обчислення, які використовуються у всьому світі, але та, яка використовується в більшості англомовних країн, чи не найпростіша - рахувати одиниці шляхом позначення вертикальних ліній, то для на кожну 5-ю марку ставимо горизонтальну лінію через попередню колекцію з чотирьох. Це кластеризує оціночні позначки в групи по 5 (і полегшує їх швидке підрахунок).

Ви збираєтеся написати програму, яка відображає суммарні позначки до заданого значення. Але, розмовляти лише в базі 5 нудно! Тому у вашій програмі також має бути можливість відображати талі в різних базах.

Вхідні дані

Вхідними даними будуть або одне, або два невід’ємних цілих значення, розділених комою (наприклад, 9або 8,4). Перше число - це значення, яке повинно відображатися підрахунком. Друге значення - основа підрахунку. Якщо друге значення не вказане, використовуйте базу 5 .

Вихідні дані

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

Введення: 12або12,5

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

Вхід: 7,3

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

Вхід: 4,2

 |   |
-+- -+-
 |   |

Введення: 6,1або 6,10(зауважте провідні пробіли)

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

Зауважте також, що основа 1 призначена для непослідовності - слід використовувати лише вертикальні лінії.

Якщо будь-яке з введених значень дорівнює 0, виходу не повинно бути (і ваша програма повинна закінчуватися витончено).

Правила

  • Це , тому найкоротша правильна реалізація (у байтах) виграє.
  • Введення / вихід може бути на будь-якому відповідному носії (наприклад, stdin / stdout, файл ...).
  • Введення може бути у вигляді декількох аргументів командного рядка або розділене пробілами тощо, якщо воно більше підходить для вашої цільової мови.
  • У висновку дозволено проходження нових рядків. Трейлінг місця не є. Це правило застосовується лише тоді, коли є вихід (тобто не тоді, коли введене значення дорівнює 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

Пітон 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 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не дорівнюють нулю.

EDIT 1: Використовуйте inputфункцію замість raw_inputтого, щоб пограти.

EDIT 2: Дякую Фалько за те, що він вказав на маленьку помилку під час моєї перевірки на нуль. Тепер наш код в основному ідентичний, менше деяких імен змінних і невеликої логіки.

EDIT 3: Завдяки тому, як Python порівнює послідовності та різні типи , ми можемо порівняти iз a, 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. Інакше наші рішення конвергуються! ;)
Фалько

@Falko Ви маєте рацію в обох аспектах! Ви знаєте, що вони говорять про великі розуми.
BeetDemGuise

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

@Falko Я думаю, що знайшов чек на 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
Геобіц

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

неозорий

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 так, це одна з вимог. Будь ласка, прочитайте коментарі до
запитання

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полягає в тому, що вона щоразу додає новий рядок :(. А для потрійного оператора додавання неможливоreturn s або 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

Луа - 219 203 байт

Я пішов зробити копії "b" копій "|", потім додаю r копії "|" в кінці. Я відчуваю, що, можливо, я мав би переходити з 'tally up' the "|" s до рядка один за одним.

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)

неозорений:

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

Просто підкрадається з трохи коротшою версією пітона.

редагувати: виправлено 0, не надрукувавши нічого і не переправившись, вийшло однаковою довжиною

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. Компілюйте з робочим компілятором на зразокtcc . Також ця функція може працювати або не працювати на 64-бітних платформах. Використовуйте обережно.

Ось оригінальна реалізація, яка не використовується для цього, базується на:

#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.