Подтвердить что ты не робот

Code Golf: Постройте меня дугой

Вызов

Самая короткая программа по количеству символов, которая принимает стандартный ввод формы X-Y R со следующими гарантиями:

  • R - неотрицательное десятичное число, меньшее или равное 8
  • X и Y - неотрицательные углы, заданные в десятичной форме как кратные 45 °; (0, 45, 90, 135 и т.д.)
  • X меньше Y
  • Y не 360, если X есть 0

И производит на стандартном выходе ASCII "дугу" от начального угла X до конечного угла Y радиуса R, где:

  • Вершина дуги представлена ​​o
  • Углы 0 и 180 представлены -
  • Углы 45 и 225 представлены /
  • Углы 90 и 270 представлены |
  • Углы 135 и 315 представлены \
  • Многоугольная область, заключенная в две строки, заполняется символом без пробелов.

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

Счастливая игра в гольф!

Многочисленные примеры

Input:

0-45 8

Вывод:

        /
       /x
      /xx
     /xxx
    /xxxx
   /xxxxx
  /xxxxxx
 /xxxxxxx
o--------

Input:

0-135 4

Вывод:

\xxxxxxxx
 \xxxxxxx
  \xxxxxx
   \xxxxx
    o----

Input:

180-360 2

Вывод:

--o--
xxxxx
xxxxx

Input:

45-90 0

Вывод:

o

Input:

0-315 2

Вывод:

xxxxx
xxxxx
xxo--
xxx\
xxxx\
4b9b3361

Ответ 1

Perl, 235 211 225 211 207 196 179 177 175 168 160 156 146 символов

<>=~/-\d+/;for$y(@a=-$'..$'){print+(map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a),$/}


Perl, используя функцию say, 161 149 139 символов

$ echo -n '<>=~/-\d+/;for$y(@a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}' | wc -c
139
$ perl -E '<>=~/-\d+/;for$y(@a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}'


Perl без конечной новой строки, 153 143 символа

<>=~/-\d+/;for$y(@a=-$'..$'){print$/,map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}


Оригинальная версия прокомментировала:

$_=<>;m/(\d+)-(\d+) (\d+)/;$e=$1/45;$f=$2/45; # parse angles and radius, angles are 0-8
for$y(-$3..$3){                               # loop for each row and col
    for$x(-$3..$3){
            $t=atan2(-$y,$x)/atan2 1,1;   # angle of this point
            $t+=8if($t<0);                # normalize negative angles
            @w=split//,"-/|\\"x2;         # array of ASCII symbols for enclosing lines
            $s.=!$x&&!$y?"o":$t==$e||$t==$f?$w[$t]:$t>$e&&$t<$f?"x":$";
            # if it origin -> "o", if it enclosing line, get symbol from array
            # if it between enclosing angles "x", otherwise space
    }
    $s.=$/;
}
print$s;


РЕДАКТИРОВАТЬ 1: Вложенные суб, операторы отношения и равенства возвращают 0 или 1.

EDIT 2: Добавлена ​​версия с комментариями.

РЕДАКТИРОВАТЬ 3: Фиксированная закрывающая линия на 360º. Char счет значительно увеличился.

EDIT 4: Добавлена ​​более короткая версия, сгибающая правила.

РЕДАКТИРОВАТЬ 5: Умное исправление для закрывающейся 360 ° линии. Кроме того, используйте число как заполнение. Обе вещи были очевидны. Мех, я должен больше спать:/

РЕДАКТИРОВАТЬ 6: Удалено ненужное m из оператора соответствия. Удалено несколько точек с запятой.

EDIT 7: Умнее регулярное выражение. До 200 символов!

EDIT 8: Множество небольших улучшений:

  • Внутренний для цикла → карта (1 char)
  • массив символов из split string → qw (3 символа)
  • встроенный массив символов (6 символов вместе с предыдущим улучшением 9 символов!)
  • Логический или → побитовый или (1 char)
  • Улучшение регулярного выражения (1 char)
  • Используйте арифметику для тестирования отрицательных углов, вдохновленную ответом Иакова (5 символов).


EDIT 9: Небольшое переупорядочение в условных операторах сохраняет 2 символа.

РЕДАКТИРОВАТЬ 10: Используйте символы для символов.

РЕДАКТИРОВАТЬ 11: Перемещенная печать внутри цикла, вдохновленная ответом Lowjacker.

EDIT 12: Добавлена ​​версия с помощью say.

РЕДАКТИРОВАТЬ 13: Повторное использование углов символов для заполнения символов, как это делает Gwell. Результат не так хорош, как Gwell, хотя это потребует еще 5 символов:) Кроме того, оператору не нужны скобки.

РЕДАКТИРОВАТЬ 14: Применить регулярное выражение непосредственно к < > . Назначьте оператор диапазона переменной, согласно предложению Адриана, чтобы ответить. Добавьте версию без последней новой строки. Обновлена ​​версия say.

РЕДАКТИРОВАТЬ 15: Больше вставки. map {block} @a → map expr, @a.

Ответ 2

Lua, 259 символов

Немного злоупотребляет предложением non-whitespace character, чтобы создать ослепительный дисплей и, что более важно, сохранить штрихи.

m=math i=io.read():gmatch("%d+")a=i()/45 b=i()/45 r=i()for y=r,-r,-1 do for x=-r,r do c=m.atan2(y,x)/m.pi*4 c=c<0 and c+8 or c k=1+m.modf(c+.5)io.write(x==0 and y==0 and'o'or c>=a and c<=b and('-/|\\-/|\\-'):sub(k,k)or c==0 and b==8 and'-'or' ')end print()end

Вход: 45-360 4

\\\|||///
\\\|||// 
\\\\|//  
--\\|/   
----o----
--//|\\--
////|\\\\
///|||\\\
///|||\\\

Возможность обработки нечетных углов

Вход: 15-75 8

           |/////
          |//////
          |//////
          |//////
          ///////
         |//////-
         ////--- 
         //-     
        o        








Ответ 3

MATLAB, 188 символов:)

input '';[w x r]=strread(ans,'%d-%d%d');l='-/|\-/|\-';[X Y]=meshgrid(-r:r);T=atan2(-Y,X)/pi*180;T=T+(T<=0)*360;T(T>w&T<x)=-42;T(T==w)=-l(1+w/45);T(T==x)=-l(1+x/45);T(r+1,r+1)=-'o';char(-T)

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

%%# Get the string variable (enclose in quotes, e.g. '45-315 4')
input ''
%%# Extract angles and length
[w x r]=strread(ans,'%d-%d%d');
%%# Store characters
l='-/|\-/|\-';
%%# Create the grid
[X Y]=meshgrid(-r:r);
%%# Compute the angles in degrees
T=atan2(-Y,X)/pi*180;
%%# Get all the angles
T=T+(T<=0)*360;
%# Negative numbers indicate valid characters
%%# Add the characters
T(T>w&T<x)=-42;
T(T==w)=-l(1+w/45);
T(T==x)=-l(1+x/45);
%%# Add the origin
T(r+1,r+1)=-'o';
%%# Display
char(-T)

Ответ 4

Mathematica 100 Chars

Вне конкуренции, потому что графика слишком совершенна:)

  f[x_-y_ z_]:[email protected][
                 {[email protected],Disk[{0,0},r,{x °,y °}],{r,z,1,-1}]
                 SetAttributes[f,HoldAll]

Вызвать f [30-70 5]

Результат

alt text http://a.imageshack.us/img80/4294/angulosgolf.png

alt text http://a.imageshack.us/img59/7892/angulos2.png

Примечание

      SetAttributes [f, HoldAll];

необходимо, потому что вход

    f[a-b c] 

иначе интерпретируется как

    f[(a-b*c)]

Ответ 5

GNU BC, 339 символов

Gnu bc из-за read(), else и логических операторов.

scale=A
a=read()/45
b=read()/45
c=read()
for(y=c;y>=-c;y--){for(x=-c;x<=c;x++){if(x==0)if(y<0)t=-2else t=2else if(x>0)t=a(y/x)/a(1)else if(y<0)t=a(y/x)/a(1)-4else t=a(y/x)/a(1)+4
if(y<0)t+=8
if(x||y)if(t==a||t==b||t==b-8){scale=0;u=(t%4);scale=A;if(u==0)"-";if(u==1)"/";if(u==2)"|";if(u==3)"\"}else if(t>a&&t<b)"x"else" "else"o"};"
"}
quit

Ответ 6

MATLAB 7.8.0 (R2009a) - 168 163 162 символа

Начиная с ответ Джейкоба и вдохновленный gwell использовать любого символа без пробела для заполнения дуги, Мне удалось выполнить следующее решение:

[w x r]=strread(input('','s'),'%d-%d%d');
l='o -/|\-/|\-';
X=meshgrid(-r:r);
T=atan2(-X',X)*180/pi;
T=T+(T<=-~w)*360;
T(T>x|T<w)=-1;
T(r+1,r+1)=-90;
disp(l(fix(3+T/45)))

И некоторый тестовый вывод:

>> arc
0-135 4
\||||////
 \|||///-
  \||//--
   \|/---
    o----

Я мог бы уменьшить его до 156 символов, удалив вызов disp, но это добавит дополнительный ans = перед выходом (что может нарушить правила форматирования вывода).

Я все еще чувствую, что есть некоторые способы уменьшить это.;)

Ответ 7

Ruby, 292 276 186 символов

x,y,r=gets.scan(/\d+/).map{|z|z.to_i};s=(-r..r);s.each{|a|s.each{|b|g=Math::atan2(-a,b)/Math::PI*180/1%360;print a|b==0?'o':g==x||g==y%360?'-/|\\'[g/45%4].chr: (x..y)===g ?'*':' '};puts}

Версия с более высоким форматом:

x, y, r = gets.scan(/\d+/).map{|z| z.to_i}
s = (-r..r)
s.each {|a|
    s.each {|b|
        g = (((Math::atan2(-a,b) / Math::PI) * 180) / 1) % 360
        print ((a | b) == 0) ? 'o' :
            (g == x || g == (y % 360)) ? '-/|\\'[(g / 45) % 4].chr :
                ((x..y) === g) ? '*' : ' '
    }
    puts
}

Я уверен, что кто-то, у кого есть больше сна, чем я, может конденсировать это больше...

Изменить 1: Переключить операторы if во внутреннем цикле на вложенный ? : оператор

Изменить 2: Сохраненный диапазон до промежуточной переменной (спасибо Adrian), использовал stdin вместо параметров CLI (спасибо за пояснение Jon), исключил массив в пользу прямого вывода, исправил ошибку, где заканчивается угол 360 не отображает строку, удаляет некоторые ненужные круглые скобки, используется деление для округления вместо .round, используется по модулю вместо условного добавления

Ответ 8

Ruby, 168 символов

Требуется работать с Ruby 1.9

s,e,r=gets.scan(/\d+/).map &:to_i;s/=45;e/=45;G=-r..r;G.map{|y|G.map{|x|a=Math.atan2(-y,x)/Math::PI*4%8;print x|y!=0?a==s||a==e%8?'-/|\\'[a%4]:a<s||a>e ?' ':8:?o};puts}

Считываемая версия:

start, _end, radius = gets.scan(/\d+/).map &:to_i
start /= 45
_end /= 45

(-radius..radius).each {|y|
    (-radius..radius).each {|x|
        angle = Math.atan2(-y, x)/Math::PI * 4 % 8
        print x|y != 0 ? angle==start || angle==_end%8 ? '-/|\\'[angle%4] : angle<start || angle>_end ? ' ' : 8 : ?o
    }
    puts
}

Ответ 9

Perl - 388 символов

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

($x,$y,$r)=split/\D/,<>;for(0..$r-1){$t=$r-1-$_;
$a.=L x$_.D.K x$t.C.J x$t.B.I x$_."\n";
$b.=M x$t.F.N x$_.G.O x$_.H.P x$t."\n"}
$_=$a.E x$r.o.A x$r."\n".$b;$x/=45;$y/=45;$S=' ';
sub A{$v=$_[0];$x==$v||$y==$v?$_[1]:$x<$v&&$y>$v?x:$S}
sub B{$x<=$_[0]&&$y>$_[0]?x:$S}
@a=!$x||$y==8?'-':$S;
[email protected],map{A$_,'\\'.qw(- / | \\)[$_%4]}1..7;
[email protected],!$x?x:$S,map{B$_}1..7;
eval"y/A-P/".(join'',@a)."/";print

Все новые строки необязательны. Это довольно просто:

  • Взять пользовательский ввод.
  • Создайте верхнюю часть ($a) и нижнюю ($b) части шаблона.
  • Создайте полный шаблон ($_).
  • Определите sub A, чтобы получить символ заполнения для угла.
  • Определите sub B, чтобы получить символ заполнения для области.
  • Создайте массив (@a) подстановочных символов с помощью A и B.
  • Выполните замену и распечатайте результаты.

Сгенерированный формат выглядит так: R= 4:

DKKKCJJJB
LDKKCJJBI
LLDKCJBII
LLLDCBIII
EEEEoAAAA
MMMFGHPPP
MMFNGOHPP
MFNNGOOHP
FNNNGOOOH

Где A-H обозначают углы и I-P обозначают области.

(По общему признанию, это, вероятно, можно было бы сыграть в гольф дальше. Операции на @a дали мне неправильный вывод, если он написан как один список, по-видимому, имеющий какое-то отношение к тому, как map играет с $_.)

Ответ 10

С# - 325 319 символов

using System;class P{static void Main(){var s=Console.ReadLine().Split(' ');
var d=s[0].Split('-');int l=s[1][0]-48,x,y,r,a=int.Parse(d[0]),b=int.Parse(d[1]);
for(y=l;y>=-l;y--)for(x=-l;x<=l;)Console.Write((x==0&&y==0?'o':a<=(r=((int)
(Math.Atan2(y,x)*57.3)+360)%360)&&r<b||r==b%360?
@"-/|\"[r/45%4]:' ')+(x++==l?"\n":""));}}

Новые строки не значимы.

Пример ввода/вывода

45-180 8
\||||||||////////
\\|||||||///////
\\\||||||//////
\\\\|||||/////
\\\\\||||////
\\\\\\|||///
\\\\\\\||//
\\\\\\\\|/
--------o
135-360 5
\
\\
\\\
\\\\
\\\\\
-----o-----
----/|\\\\\
---//||\\\\
--///|||\\\
-////||||\\
/////|||||\

Ответ 11

Java - 304 символа


class A{public static void main(String[]a){String[]b=a[0].split("-");int e=new Integer(b[1]),r=new Integer(a[1]),g,x,y=r;for(;y>=-r;y--)for(x=-r;x<=r;)System.out.print((x==0&y==0?'o':new Integer(b[0])<=(g=((int)(Math.atan2(y,x)*57.3)+360)%360)&g<e|g==e%360?"-/|\\".charAt(g/45%4):' ')+(x++<r?"":"\n"));}}

Более читаемая версия:

class A{
 public static void main(String[]a){
  String[]b=a[0].split("-");
  int e=new Integer(b[1]),r=new Integer(a[1]),g,x,y=r;
  for(;y>=-r;y--)for(x=-r;x<=r;)System.out.print((
   x==0&y==0
    ?'o'
    :new Integer(b[0])<=(g=((int)(Math.atan2(y,x)*57.3)+360)%360)&g<e|g==e%360
     ?"-/|\\".charAt(g/45%4)
     :' '
   )+(x++<r?"":"\n"));
 }
}

Ответ 12

C (902 байт)

Это не использует тригонометрические функции (например, оригинальную версию perl), поэтому она довольно "раздута". Во всяком случае, вот моя первая подача кода-гольфа:

#define V(r) (4*r*r+6*r+3)
#define F for(i=0;i<r;i++)
#define C ;break;case
#define U p-=2*r+2,
#define D p+=2*r+2,
#define R *++p=
#define L *--p=
#define H *p='|';
#define E else if
#define G(a) for(j=0;j<V(r)-1;j++)if(f[j]==i+'0')f[j]=a;
#define O(i) for(i=0;i<2*r+1;i++){
main(int i,char**v){char*p,f[V(8)];
int j,m,e,s,x,y,r;p=*++v;x=atoi(p);while(*p!=45)p++;
char*h="0123";y=atoi(p+1);r=atoi(*++v);
for(p=f+2*r+1;p<f+V(r);p+=2*r+2)*p=10;
*(p-2*r-2)=0;x=x?x/45:x;y/=45;s=0;e=2*r;m=r;p=f;O(i)O(j)
if(j>e)*p=h[0];E(j>m)*p=h[1];E(j>s)*p=h[2];else*p=h[3];p++;}
if(i+1==r){h="7654";m--;e--;}E(i==r){s--;}E(i>r){s--;e++;}
else{s++;e--;}p++;}for(p=f+V(r)/2-1,i=0;i<r;i++)*++p=48;
for(i=0;i<8;i++)if(i>=x&&i<y){G(64);}else G(32);
y=y==8?0:y;q:p=f+V(r)/2-1;*p='o';switch(x){
C 0:F R 45 C 1:F U R 47 C 2:F U H C 3:F U L 92
C 4:F L 45 C 5:F D L 47 C 6:F D H C 7:F D R 92;}
if(y!=8){x=y;y=8;goto q;}puts(f);}

также, #define выглядят довольно уродливо, но они сохраняют около 200 байт, поэтому я все равно их сохранил. Он действительно ANSI C89/C90 и компилируется с очень небольшим количеством предупреждений (два о atoi и puts и два о искалеченной форме main).