Код Гольф - π день

Соревнование

Рекомендации по код-гольфу на SO

Самый короткий код по количеству символов для отображения круга радиуса R с использованием символа *, за которым следует аппроксимация π.

Введите одно число, R.

Поскольку большинство компьютеров имеют соотношение почти 2: 1, вы должны выводить только строки, где y нечетный. Это означает, что если значение R нечетное, вы должны вывести R-1 строк. Для R=13 есть новый тестовый пример, чтобы прояснить его.

eg.

Input
    5
Output      Correct                          Incorrect

        3    *******                    4      *******
        1   *********                   2     *********
       -1   *********                   0    ***********
       -3    *******                   -2     *********
           2.56                        -4      *******
                                            3.44

Изменить: из-за широко распространенной путаницы, вызванной нечетными значениями R, будут приняты любые решения, которые проходят 4 тестовых примера, приведенных ниже.

Приближение числа π дается путем деления удвоенного количества символов * на .
Приближение должно быть правильным до не менее 6 значащих цифр.
Начальные и конечные нули разрешены, поэтому например, любой из 3, 3.000000, 003 принимается для входов 2 и 4.

Счетчик кода включает ввод / вывод (т.е. полная программа).

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

Input
    2
Output
     *** 
     *** 
    3.0

Input
    4
Output
      *****  
     ******* 
     ******* 
      *****  
    3.0

Input
    8
Output
         *******     
      *************  
     *************** 
     *************** 
     *************** 
     *************** 
      *************  
         *******     
    3.125

Input
    10
Output
          *********      
       ***************   
      *****************  
     ******************* 
     ******************* 
     ******************* 
     ******************* 
      *****************  
       ***************   
          *********      
    3.16

Бонусный тестовый пример

Input
    13
Output

           *************       
        *******************    
       *********************   
      ***********************  
     ************************* 
     ************************* 
     ************************* 
     ************************* 
      ***********************  
       *********************   
        *******************    
           *************                                          
    2.98224852071

person Community    schedule 13.03.2010    source источник
comment
Возможно, вы захотите уточнить, находится ли ввод в командной строке или на стандартном вводе.   -  person Greg Hewgill    schedule 14.03.2010
comment
@Greg Hewgill, не стесняйтесь выбирать тот, который наиболее удобен для используемого вами языка :)   -  person John La Rooy    schedule 14.03.2010
comment
@Greg Hewgill, Некоторые (то есть очень немногие) реализации языков программирования не имеют понятия командной строки.   -  person Joey Adams    schedule 14.03.2010
comment
@LiraNuna, спасибо. Это значит, что король вопросов по гольфу говорит о многом :)   -  person John La Rooy    schedule 15.03.2010
comment
Вы упомянули, что выходные данные могут иметь начальные (03) или конечные нули (3,0), а как насчет ввода?   -  person Ponkadoodle    schedule 15.03.2010
comment
@wallacoloo, честно говоря, ваш ответ должен работать с вводом, указанным в тестовых примерах. Если он также работает с 08, 8e0 и 8.00, это тоже нормально.   -  person John La Rooy    schedule 15.03.2010
comment
Я заметил, что некоторые ответы следуют правилу вывода только строк, где y нечетно. Учитывая нечетное значение r (не показано в тестовых примерах), большинство будет выводить строки с четным y!   -  person MtnViewMark    schedule 15.03.2010
comment
@MtnViewMark, я прокомментировал лидерам и добавил пример к вопросу   -  person John La Rooy    schedule 16.03.2010
comment
Я отредактировал свою заявку (104 символа python), чтобы продемонстрировать свои вопросы о строках с нечетными номерами.   -  person lunixbochs    schedule 16.03.2010
comment
Я решил сделать тест на нечетное число необязательным, так как он вызывает слишком много проблем и нарушает принцип развлечения.   -  person John La Rooy    schedule 16.03.2010
comment
Проблема злоупотребления правилом: сделайте код короче, чем любой другой код, за счет только поддержки 4 необходимых тестовых примеров.   -  person Brian    schedule 16.03.2010
comment
@ Брайан, удачи с этим :)   -  person John La Rooy    schedule 16.03.2010
comment
подожди, мы можем обмануть? обновил свой ответ третьим вариантом: D   -  person lunixbochs    schedule 16.03.2010


Ответы (26)


В dc: 88 и 93 93 94 96 102 105 129 138 141 символы

На всякий случай я использую OpenBSD и некоторые якобы непереносимые расширения.

93 символа. Это основано на той же формуле, что и решение FORTRAN (результаты немного отличаются от результатов тестов). Вычисляет X ^ 2 = R ^ 2-Y ^ 2 для каждого Y

[rdPr1-d0<p]sp1?dsMdd*sRd2%--
[dd*lRr-vddlMr-32rlpxRR42r2*lpxRRAP4*2+lN+sN2+dlM>y]
dsyx5klNlR/p

88 символов. Итерационное решение. Соответствует тестовым случаям. Для каждого X и Y проверяется, если X ^ 2 + Y ^ 2 ‹= R ^ 2

1?dsMdd*sRd2%--sY[0lM-[dd*lYd*+lRr(2*d5*32+PlN+sN1+dlM!<x]dsxxAPlY2+dsYlM>y]
dsyx5klNlR/p

Для запуска dc pi.dc.

Вот более старая аннотированная версия:

# Routines to print '*' or ' '. If '*', increase the counter by 2
[lN2+sN42P]s1
[32P]s2
# do 1 row
# keeping I in the stack
[
 # X in the stack
 # Calculate X^2+Y^2 (leave a copy of X)
 dd*lYd*+ 
 #Calculate X^2+Y^2-R^2...
 lR-d
 # .. if <0, execute routine 1 (print '*')
 0>1
 # .. else execute routine 2 (print ' ')
 0!>2 
 # increment X..
 1+
 # and check if done with line (if not done, recurse)
 d lM!<x
]sx
# Routine to cycle for the columns
# Y is on the stack
[
  # push -X
  0lM- 

  # Do row
  lxx 
  # Print EOL
  10P
  # Increment Y and save it, leaving 2 copies
  lY 2+ dsY 
  # Check for stop condition
  lM >y
]sy
# main loop
# Push Input value
[Input:]n?
# Initialize registers
# M=rows
d sM
# Y=1-(M-(M%2))
dd2%-1r-sY
# R=M^2
d*sR
# N=0
0sN
[Output:]p
# Main routine
lyx
# Print value of PI, N/R
5klNlR/p
person Community    schedule 16.03.2010
comment
Не работает с linux dc, но я могу подтвердить, что он работает с openbsd. Потрясающий! - person John La Rooy; 17.03.2010
comment
@Carlos, да, оператор ( очень удобен. жаль, что он остается нереализованным в DC, который поставляется с Linux - person John La Rooy; 18.03.2010
comment
@gnibbler - полное переписывание команды dc с использованием подпрограмм больших чисел bn (3) впервые появилось в OpenBSD 3.5. Я этого не знал. Включены несколько хороших новых операторов, но они помечены как непереносимые расширения. - person Carlos Gutiérrez; 18.03.2010
comment
Да, только оператор (оператор позволил пролить 6 ударов! - person Dan Andreatta; 18.03.2010

C: 131 символ

(На основе решения Джои на C ++)

main(i,j,c,n){for(scanf("%d",&n),c=0,i|=-n;i<n;puts(""),i+=2)for(j=-n;++j<n;putchar(i*i+j*j<n*n?c++,42:32));printf("%g",2.*c/n/n);}

(Измените i|=-n на i-=n, чтобы удалить поддержку случаев нечетных чисел. Это просто сокращает количество символов до 130.)

По кругу:

      main(i,j,
   c,n){for(scanf(
  "%d",&n),c=0,i=1|
 -n;i<n;puts(""),i+=
 0x2)for(j=-n;++j<n;
 putchar(i*i+j*j<n*n
 ?c++,0x02a:0x020));
  printf("%g",2.*c/
   n/n);3.1415926;
      5358979;}
person Community    schedule 14.03.2010
comment
Мне нравится, как вы добавили кружки в код, чтобы превратить его в кружок. Было бы предпочтительнее +000? - person Potatoswatter; 14.03.2010
comment
поздравляю, j * j ++ - неопределенное поведение - person sellibitze; 14.03.2010
comment
@sellibitze: Ах да. Обновление должно было устранить неопределенное поведение (и устранить ошибку нечетных чисел). - person kennytm; 14.03.2010
comment
Есть запись IOCCC, очень похожая на эти строки. Он аппроксимирует число "пи", считая собственные символы в форме круга. - person Joey Adams; 15.03.2010
comment
Может быть на 2 символа меньше, если превратить ‹= в› сравнение. - person Jasper Bekkers; 16.03.2010
comment
разве это не был бы только один персонаж ...? - person Ponkadoodle; 16.03.2010
comment
Нет, потому что он сравнивает с ‹= дважды. - person Jasper Bekkers; 16.03.2010
comment
@ Джаспер: Как? i<=n должен быть таким из-за цикла for, i*i+j*j<=n*n должен быть таким, иначе выражение c++,42 требует скобок. - person kennytm; 16.03.2010
comment
Вы можете просто написать n>i и n*n>i*i+j*j, они означают одно и то же. - person Jasper Bekkers; 16.03.2010
comment
Как main() принимает четыре int аргумента? - person David R Tribble; 16.03.2010
comment
@Load: 5.1.2.2.1 / 1: функция, вызываемая при запуске программы, называется main. Он должен быть определен… или каким-либо другим способом, определяемым реализацией. Это потому, что реализация может принимать эту форму. - person kennytm; 16.03.2010
comment
Если аргументов командной строки нет, i=1 уже, поэтому вы можете сказать i|=-n - person John La Rooy; 17.03.2010
comment
@KennyTM: Использование нестандартного main() делает программу непереносимой. Это то, что вы хотели? - person David R Tribble; 19.03.2010

XSLT 1.0

Ради удовольствия, вот версия XSLT. Не совсем кодовый материал для гольфа, но он решает проблему каким-то странно-функциональным-XSLT-способом :)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" >
  <xsl:output method="html"/>

  <!-- Skip even lines -->
  <xsl:template match="s[@y mod 2=0]">
    <xsl:variable name="next">
      <!-- Just go to next line.-->
      <s R="{@R}" y="{@y+1}" x="{-@R}" area="{@area}"/>
    </xsl:variable>
    <xsl:apply-templates select="msxsl:node-set($next)"/>
  </xsl:template>

  <!-- End of the line?-->
  <xsl:template match="s[@x &gt; @R]">
    <xsl:variable name="next">
      <!-- Go to next line.-->
      <s R="{@R}" y="{@y+1}" x="{-@R}" area="{@area}"/>
    </xsl:variable><!-- Print LF-->&#10;<xsl:apply-templates 
      select="msxsl:node-set($next)"/>
  </xsl:template>

  <!-- Are we done? -->
  <xsl:template match="s[@y &gt; @R]">
    <!-- Print PI approximation -->
    <xsl:value-of select="2*@area div @R div @R"/>
  </xsl:template>

  <!-- Everything not matched above -->
  <xsl:template match="s">
    <!-- Inside the circle?-->
    <xsl:variable name="inside" select="@x*@x+@y*@y &lt; @R*@R"/>
    <!-- Print "*" or " "-->
    <xsl:choose>
      <xsl:when test="$inside">*</xsl:when>
      <xsl:otherwise>&#160;</xsl:otherwise>
    </xsl:choose>

    <xsl:variable name="next">
      <!-- Add 1 to area if we're inside the circle. Go to next column.-->
      <s R="{@R}" y="{@y}" x="{@x+1}" area="{@area+number($inside)}"/>
    </xsl:variable>
    <xsl:apply-templates select="msxsl:node-set($next)"/>
  </xsl:template>

  <!-- Begin here -->
  <xsl:template match="/R">
    <xsl:variable name="initial">
      <!-- Initial state-->
      <s R="{number()}" y="{-number()}" x="{-number()}" area="0"/>
    </xsl:variable>
    <pre>
      <xsl:apply-templates select="msxsl:node-set($initial)"/>
    </pre>
  </xsl:template>
</xsl:stylesheet>

Если вы хотите протестировать его, сохраните его как pi.xslt и откройте следующий XML-файл в IE:

<?xml version="1.0"?> 
<?xml-stylesheet href="pi.xslt" type="text/xsl" ?> 
<R> 
  10 
</R> 
person Community    schedule 15.03.2010
comment
мой ‹eyes› ‹/eyes›! Очки, они ‹do› ничего ‹/do›! - person Jimmy; 16.03.2010
comment
Черт! Боюсь, вы могли превзойти мое решение HyperCard по уникальности: D - person Joey Adams; 16.03.2010
comment
Не могу поверить, что ты сказал "открой" ... IE - person harpo; 17.03.2010
comment
Хех, да, когда-то у нас был только IE, а XML с XSLT был решением всех наших проблем. Старые добрые времена! :) - person Danko Durbić; 17.03.2010
comment
XSL версии 1.0 вау, я помню, с нетерпением ждал версии 2, но к тому времени, когда она вышла, я уже двинулся дальше. - person gradbot; 25.03.2010

Perl, 95 96 99 106 109 110 119 символов:

$t+=$;=1|2*sqrt($r**2-($u-2*$_)**2),say$"x($r-$;/2).'*'x$;for 0..
($u=($r=<>)-1|1);say$t*2/$r**2

(Новая строка может быть удалена и существует только во избежание полосы прокрутки)

Ура! Круговая версия!

    $t+=$;=
 1|2*sqrt($r**
2-($u-2*$_)**2)
,say$"x($r-$;/2
).'*'x$;for 0..
($u=($r=<>)-1|1
 );$pi=~say$t*
    2/$r**2

Для непосвященных длинная версия:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

# Read the radius from STDIN
my $radius = <>;

# Since we're only printing asterisks on lines where y is odd,
# the number of lines to be printed equals the size of the radius,
# or (radius + 1) if the radius is an odd number.
# Note: we're always printing an even number of lines.
my $maxline = ($radius - 1) | 1;

my $surface = 0;

# for ($_ = 0; $_ <= $maxline; $_++), if you wish
for (0 .. $maxline) {
    # First turn 0 ... N-1 into -(N/2) ... N/2 (= Y-coordinates),
    my $y = $maxline - 2*$_;

    # then use Pythagoras to see how many stars we need to print for this line.
    # Bitwise OR "casts" to int; and: 1 | int(2 * x) == 1 + 2 * int(x)
    my $stars = 1 | 2 * sqrt($radius**2-$y**2);
    $surface += $stars;    

    # $" = $LIST_SEPARATOR: default is a space,
    # Print indentation + stars 
    # (newline is printed automatically by say)
    say $" x ($radius - $stars/2) . '*' x $stars;
}

# Approximation of Pi based on surface area of circle:
say $surface*2/$radius**2;
person Community    schedule 14.03.2010
comment
Это, безусловно, самый нечитаемый код, который я видел за всю свою жизнь. - person Chris Marisic; 14.03.2010
comment
Думаю, вы тогда еще не видели APL. - person Peter Wone; 14.03.2010
comment
@Chris Marisic: Вы проверяли другие вопросы / темы с тегами code-golf? :) Я видел гораздо больше нечитаемых примеров. - person BalusC; 14.03.2010
comment
@Peter: В отличие от большинства, я видел и писал APL. Чтобы привыкнуть к его специальным символам, потребуется пара недель, но после этого он станет вполне читаемым. Даже спустя пару десятилетий, чтобы привыкнуть, Perl все еще намного хуже. - person Jerry Coffin; 14.03.2010
comment
Я только пытался пошутить. Мне всегда казалось, что Perl ничем не отличается от линейного шума TTY. Некоторые шутки однажды окрестили его первым в мире языком, предназначенным только для записи. - person Peter Wone; 14.03.2010
comment
Итак, кто-нибудь тогда напишет APL-версию? - person Nicholas Riley; 14.03.2010
comment
111 символов, $r=<>;$t+=$n=1+2*int sqrt($r**2-($u-2*$_)**2),print$"x($r-$n/2).'*'x$n.$/for(0..($u=$r-1+$r%2));print$t*2/$r**2 - person Hasturkun; 14.03.2010
comment
@Hasturkun: Обновлено. Хорошее использование $" и $/! Я бы об этом не подумал. - person mercator; 14.03.2010
comment
Использование say вместо print в конце цикла сохранит 3 символа, используемые для печати новой строки. - person sundar - Remember Monica; 15.03.2010
comment
Эта версия в настоящее время печатает четные строки, когда R нечетный. - person John La Rooy; 16.03.2010
comment
@sundar, хммм, я думал об этом, но я протестировал это, сохранив в файл, который затем требует _1 _... Я оставлю его. - person mercator; 16.03.2010
comment
Вы можете запустить его, используя perl -M5.01 - person John La Rooy; 16.03.2010
comment
@gnibbler, да ладно, спасибо ... Мне нужно подумать о странном R сегодня вечером. Я думал, что он печатает нужное количество строк. Начало координат находится в центре, между двумя средними линиями. Разве это не означает, что для R = 13 верх и низ должны быть в точках (0,13) и (0, -13), в результате чего получается 14 нечетных строк? В вашем примере вывода всего 12 строк. - person mercator; 16.03.2010
comment
@mercator, поскольку я печатаю '*' только для точек внутри круга, верхняя и нижняя строки будут пустыми. Вы можете сделать 14 строк, если хотите, пустые строки необязательны. - person John La Rooy; 16.03.2010
comment
По сей день Perl кажется наиболее сжимаемым языком на планете Земля. - person flq; 16.03.2010
comment
@mercator, я решил сделать тест на нечетное число необязательным, так как он вызывает слишком много проблем и нарушает принцип удовольствия - person John La Rooy; 16.03.2010
comment
Измените $n на некоторую доступную для записи и непостижимую переменную, например $;. Затем вы можете удалить пробел перед for. - person mob; 17.03.2010
comment
Так что версия C почти такая же короткая? Думаю, хватит писать нечитаемый, но компактный код Perl ... - person Prof. Falken; 18.03.2010
comment
@gnibbler, я не хочу сейчас сбивать свой собственный ответ, но в чем именно проблемы с нечетными числами? Единственная проблема, которую я вижу, это то, можно ли печатать звезды на самом круге или нет. Это не ясно сказано в задаче, и я не думал об этом до ваших комментариев. Эта проблема возникает только на нечетных радиусах из-за (0, ± R) и троек Пифагора (mathworld.wolfram .com / PythagoreanTriple.html), например (± 12, ± 5) на круге R = 13. - person mercator; 19.03.2010
comment
@mercator, да, вы попали в точку, и поскольку изначально не было тестового случая с тройкой, мне показалось нечестным добавлять дополнительные условия, которые нарушили бы уже отправленные ответы. Тем более, что другие люди основывали свои ответы на уже существующих. - person John La Rooy; 19.03.2010
comment
@gnibbler: вместо -M5.01 вы можете использовать -E. Вы сэкономите четыре символа, если передадите все в командной строке. :) - person Robert P; 07.04.2010
comment
@NicholasRiley Здесь, извините за поздний ответ :) stackoverflow.com/a/17823939/517371 - person Tobia; 24.07.2013

FORTRAN - 101 символ

$ f95 piday.f95 -o piday && echo 8 | ./piday


READ*,N
DO I=-N,N,2
M=(N*N-I*I)**.5
PRINT*,(' ',J=1,N-M),('*',J=0,M*2)
T=T+2*J
ENDDO
PRINT*,T/N/N
END


    READ*,N
  K=N/2*2;DO&
 I=1-K,N,2;M=&
(N*N-I*I)**.5;;
PRINT*,(' ',J=&
1,N-M),('*',J=&
0,M*2);T=T+2*J;
 ENDDO;PRINT*&
  ,T/N/N;END;
    !PI-DAY
person Community    schedule 15.03.2010
comment
Постойте, а я хоть форматирование было важно в Фортране? У вас есть буквы в столбце 1! - person Joel; 18.03.2010
comment
Из того, что я видел, большинство людей все еще застревают на Fortan77. - person Joel; 22.03.2010
comment
Мне нравится, как версия круга выглядит как Звезда Смерти. - person mskfisher; 05.11.2010

Машинный код x86: 127 байт

Ассемблер Intel: 490 символов

    mov si,80h
    mov cl,[si]
    jcxz ret
    mov bx,10
    xor ax,ax
    xor bp,bp
    dec cx
  a:mul bx
    mov dl,[si+2]
    sub dl,48
    cmp dl,bl
    jae ret
    add ax,dx
    inc si
    loop a
    mov dl,al
    inc dl
    mov dh,al
    add dh,dh
    mov ch,dh
    mul al
    mov di,ax
  x:mov al,ch
    sub al,dl
    imul al
    mov si,ax
    mov cl,dh
  c:mov al,cl
    sub al,dl
    imul al
    add ax,si
    cmp ax,di
    mov al,32
    ja y
    or al,bl
    add bp,2
  y:int 29h
    dec cl
    jnz c
    mov al,bl
    int 29h
    mov al,13
    int 29h
    sub ch,2
    jnc x
    mov ax,bp
    cwd
    mov cl,7
  e:div di
    cmp cl,6
    jne z
    pusha
    mov al,46
    int 29h
    popa
  z:add al,48
    int 29h
    mov ax,bx
    mul dx
    jz ret
    dec cl
    jnz e
    ret

Эта версия также обрабатывает бонусный тестовый пример и занимает 133 байта:

    mov si,80h
    mov cl,[si]
    jcxz ret
    mov bx,10
    xor ax,ax
    xor bp,bp
    dec cx
  a:mul bx
    mov dl,[si+2]
    sub dl,48
    cmp dl,bl
    jae ret
    add ax,dx
    inc si
    loop a
    mov dl,al
    rcr dl,1
    adc dl,dh
    add dl,dl
    mov dh,dl
    add dh,dh
    dec dh
    mov ch,dh
    mul al
    mov di,ax
  x:mov al,ch
    sub al,dl
    imul al
    mov si,ax
    mov cl,dh
  c:mov al,cl
    sub al,dl
    imul al
    add ax,si
    cmp ax,di
    mov al,32
    jae y
    or al,bl
    add bp,2
  y:int 29h
    dec cl
    jnz c
    mov al,bl
    int 29h
    mov al,13
    int 29h
    sub ch,2
    jnc x
    mov ax,bp
    cwd
    mov cl,7
  e:div di
    cmp cl,6
    jne z
    pusha
    mov al,46
    int 29h
    popa
  z:add al,48
    int 29h
    mov ax,bx
    mul dx
    jz ret
    dec cl
    jnz e
    ret
person Community    schedule 15.03.2010
comment
Интересно, что в некоторых языках высокого уровня количество символов меньше, чем в двоичном коде. - person Colin Valliant; 17.03.2010
comment
@Alcari: если вы включите весь код в библиотеки, которые используют языки более высокого уровня, их количество символов будет значительно выше. В ассемблере выполнение printf("%f",a/b) нетривиально, для этого нет единой инструкции, и моя реализация выше предполагает, что 0 ‹= a / b‹ 10, и что операция является делением, а a и b - целые числа. - person Skizz; 17.03.2010

Python: 101 104 107 110 символов

На основе другой версии Python Николаса Райли.

r=input()
t=0
i=1
exec"n=1+int((2*i*r-i*i)**.5)*2;t+=2.*n/r/r;print' '*(r-n/2)+'*'*n;i+=2;"*r
print t

Благодарим AlcariTheMad за некоторую математику.


Ах, нечетные имеют индекс с нулем в середине, все объясняет.

Бонусный Python: 115 символов (быстро собраны вместе)

r=input()
t=0
i=1
while i<r*2:n=1+int((2*i*r-i*i)**.5)*2;t+=2.*n/r/r;print' '*(r-n/2)+'*'*n;i+=2+(r-i==2)*2
print t
person Community    schedule 14.03.2010
comment
Вау, да, "+" лучше -1 и в любой день. Еще одна техника, которую я выбросил из головы, потому что это почти никогда не бывает правильным :-) - person Nicholas Riley; 15.03.2010
comment
Раньше я использовал C и даже не смотрел на Python. Эти 104 символа более читабельны, чем приведенный выше C ++. Удивительный. Может мне стоит выучить Python ... - person Dean Rather; 15.03.2010
comment
@Dean: Одна из основных целей Python - облегчить чтение и запись. - person Colin Valliant; 15.03.2010
comment
а вы тоже об использовании exec с вашим 104-символьным ответом? :) - person John La Rooy; 19.03.2010
comment
Мне нужно было бы свернуть собственное сжатие - zlib, маршаллинг и т. Д. Все вышло больше, чем фактический код. - person lunixbochs; 19.03.2010
comment
как насчет использования exec вместо цикла while? ;) - person John La Rooy; 20.03.2010
comment
Мы рассматривали возможность взять скомпилированный объект кода + marshal + zlib + base64 и выполнить его, но результат составляет около 350 символов. Фактически, байт-код, который использует Python, длиннее, чем сам исходный код. - person Colin Valliant; 20.03.2010

Powershell, 119 113 109 символов

($z=-($n=$args[($s=0)])..$n)|?{$_%2}|%{$l="";$i=$_
$z|%{$l+=" *"[$i*$i+$_*$_-lt$n*$n-and++$s]};$l};2*$s/$n/$n

а вот версия покрасивее:

( $range = -( $R = $args[ ( $area = 0 ) ] ) .. $R ) | 
  where { $_ % 2 } |
  foreach {
    $line = ""
    $i = $_
    $range | foreach {
        $line += " *"[ $i*$i + $_*$_ -lt $R*$R -and ++$area ]
    }
    $line
 }
 2 * $area / $R / $R
person Community    schedule 14.03.2010
comment
@Thor: Надеюсь, что нет, но это, наверное, самая уродливая вещь, которую я когда-либо писал :) - person Danko Durbić; 15.03.2010
comment
Спасибо за более красивую версию =) - person Thor Hovden; 15.03.2010

HyperTalk: 237 символов

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

function P R
  put""into t
  put 0into c
  repeat with i=-R to R
    if i mod 2≠0then
      repeat with j=-R to R
        if i^2+j^2≤R^2then
          put"*"after t
          add 1to c
        else
          put" "after t
        end if
      end repeat
      put return after t
    end if
  end repeat
  return t&2*c/R/R
end P

Поскольку HyperCard 2.2 не поддерживает stdin / stdout, вместо него предоставляется функция.

person Community    schedule 14.03.2010
comment
Гиперкарта, мистер Адамс? Шутки в сторону? Это в высшей степени неожиданно. - person Kawa; 14.03.2010
comment
@Kawa: Вот почему я опубликовал это :) Кроме того, code golf - хороший способ создать набор тестов на тот случай, если я решу написать интерпретатор HyperTalk в будущем. - person Joey Adams; 14.03.2010
comment
Ха! Я бы хотел это увидеть, XD - person Kawa; 15.03.2010
comment
Если вы когда-нибудь решите написать этот интерпретатор или захотите присоединиться к работе над уже существующим, дайте мне знать, и я могу добавить упоминание об этом на hypercard.org, и мне будет любопытно, как это пойдет :-) - person uliwitness; 27.10.2013

C #: 209202 201 символ:

using C=System.Console;class P{static void Main(string[]a){int r=int.Parse(a[0]),s=0,i,x,y;for(y=1-r;y<r;y+=2){for(x=1-r;x<r;s+=i)C.Write(" *"[i=x*x+++y*y<=r*r?1:0]);C.WriteLine();}C.Write(s*2d/r/r);}}

Unminified:

using C = System.Console;
class P {
  static void Main(string[] arg) {
    int r = int.Parse(arg[0]), sum = 0, inside, x, y;
    for (y = 1 - r; y < r; y += 2) {
      for (x = 1 - r; x < r; sum += inside)
        C.Write(" *"[inside = x * x++ + y * y <= r * r ? 1 : 0]);
      C.WriteLine();
    }
    C.Write(sum * 2d / r / r);
  }
}
person Community    schedule 13.03.2010
comment
Я не очень хорошо знаю C #, но разве вы не можете использовать string[]a и 1-r (вместо -1+r)? - person kennytm; 14.03.2010
comment
@ Кенни: Ты прав. :) Это спасает три символа, а потом мне удалось избавиться от еще пяти. - person Guffa; 14.03.2010
comment
Заметил то первое, совершенно пропустил -r+1 штуку. - person Dykam; 14.03.2010
comment
Кроме того, тоже был замечен x*xx+++y*y, но на первый взгляд это безумие. - person Dykam; 14.03.2010
comment
Я взял на себя смелость удалить еще один байт ;-) - person Joey; 15.03.2010
comment
Хороший. На неуплотненные тоже один раз нанесла. - person Dykam; 15.03.2010
comment
Используя goto, я могу получить 202 символа ... a:[...]goto a; Но не могу удалить отдельные фрагменты из for. - person Dykam; 15.03.2010

Haskell 139 145 147 150 230 символов:

x True=' ';x _='*'
a n=unlines[[x$i^2+j^2>n^2|j<-[-n..n]]|i<-[1-n,3-n..n]]
b n=a n++show(sum[2|i<-a n,i=='*']/n/n)
main=readLn>>=putStrLn.b

Обработка нечетных чисел: 148 символов:

main=do{n<-readLn;let{z k|k<n^2='*';z _=' ';c=[[z$i^2+j^2|j<-[-n..n]]|i<-[1,3..n]];d=unlines$reverse c++c};putStrLn$d++show(sum[2|i<-d,i=='*']/n/n)}

150 символов: (На основе версии C.)

a n=unlines[concat[if i^2+j^2>n^2then" "else"*"|j<-[-n..n]]|i<-[1-n,3-n..n]]
main=do n<-read`fmap`getLine;putStr$a n;print$2*sum[1|i<-a n,i=='*']/n/n

230 символов:

main=do{r<-read`fmap`getLine;let{p=putStr;d=2/fromIntegral r^2;l y n=let c m x=if x>r then p"\n">>return m else if x*x+y*y<r*r then p"*">>c(m+d)(x+1)else p" ">>c m(x+1)in if y>r then print n else c n(-r)>>=l(y+2)};l(1-r`mod`2-r)0}

Unminified:

main = do r <- read `fmap` getLine
          let p = putStr
              d = 2/fromIntegral r^2
              l y n = let c m x = if x > r
                                  then p "\n" >> return m
                                  else if x*x+y*y<r*r
                                       then p "*" >> c (m+d) (x+1)
                                       else p " " >> c m (x+1)
                      in if y > r
                         then print n
                         else c n (-r) >>= l (y+2)
          l (1-r`mod`2-r) 0

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

person Community    schedule 14.03.2010
comment
Отрубил еще 2, избавившись от d и добавив вместо него 1, а затем напечатав 2 * n / from Integral r ^ 2 - person Steve; 14.03.2010
comment
Удалили 3 символа с помощью нескольких уловок Haskell. Мне нравится, что в Haskell часто нет затрат на несколько строк (новая строка против точки с запятой), и, следовательно, наш код-гольф обычно читается! - person MtnViewMark; 14.03.2010
comment
Строго говоря, версия с 145 символами работает, только если ввод четный. Но в любом случае очень приятно. - person Steve; 16.03.2010
comment
Укорочена линия ввода / вывода. Я думаю, все еще должна быть возможность сохранить еще несколько символов, вставив функцию defs в блок main = do {... let {...} ...}. - person comingstorm; 16.03.2010
comment
@comingstorm: Круто! Я не знал о readLn. Это поможет многим код-гольфам на Haskell. @ Стив: Ага, я все еще пытаюсь найти наиболее эффективный способ исправить это. - person MtnViewMark; 16.03.2010
comment
Как насчет x y|y=' '|0<1='*'for x True=' ';x _='*'? - person fuz; 11.03.2011
comment
@FUZxxl x b|b=' ';x _='*' - еще одно предложение, такой же длины, как ваше. Еще нравится x b=last$'*':[' '|b], но он на три символа длиннее ... - person danr; 12.04.2012

Рубин, 96 символов

(на основе решения Guffa C #):

r=gets.to_f
s=2*t=r*r
g=1-r..r
g.step(2){|y|g.step{|x|putc' * '[i=t<=>x*x+y*y];s+=i}
puts}
p s/t

109 символов (бонус):

r=gets.to_i
g=-r..r
s=g.map{|i|(g.map{|j|i*i+j*j<r*r ?'*':' '}*''+"\n")*(i%2)}*''
puts s,2.0/r/r*s.count('*')
person Community    schedule 14.03.2010
comment
Спасибо! Мне неловко видеть, насколько нечитабельным может быть Ruby ... :) - person Mladen Jablanović; 15.03.2010
comment
вы также можете использовать p s вместо puts s :) - person John La Rooy; 15.03.2010
comment
Хорошие свежие идеи - мне нравится, что вы используете g с двумя разными размерами шага и ‹=›, чтобы избежать преобразования кода из логического - person John La Rooy; 21.03.2010

PHP: 117

На основе dev-null-dweller

for($y=1-$r=$argv[1];$y<$r;$y+=2,print"\n")for($x=1-$r;$x<$r;$x++)echo$r*$r>$x*$x+$y*$y&&$s++?'*':' ';echo$s*2/$r/$r;
person Community    schedule 15.03.2010

Вы, ребята, слишком много думаете.

switch (r) {
   case 1,2:
      echo "*"; break;
   case 3,4:
      echo " ***\n*****\n ***"; break;
   // etc.
}
person Community    schedule 15.03.2010
comment
Количество персонажей немного выходит из-под контроля, вам не кажется? :) - person John La Rooy; 16.03.2010
comment
Не масштабируется. Неподдерживаемый! - person spoulson; 16.03.2010
comment
Я попытался максимально сжать чит тестового примера, но он все равно оказался немного больше, чем мое реальное решение: P - person lunixbochs; 16.03.2010
comment
+1, всегда сначала делай самое очевидное ... если кому-то это не нравится, громко жалуйся, что спецификация недостаточно ясна - person Mizipzor; 19.03.2010
comment
У Брайана была полусерьезная попытка создать специальный корпус для тестовых примеров, вы должны проголосовать и за него, если вам нравится этот ответ;) stackoverflow.com/questions/ 2457995 - person John La Rooy; 22.03.2010

J: 47, 46, 45

Та же основная идея, что и в других решениях, то есть r ^ 2 ‹= x ^ 2 + y ^ 2, но нотация J, ориентированная на массив, упрощает выражение:

c=:({&' *',&":2*+/@,%#*#)@:>_2{.\|@j./~@i:@<:

Вы бы назвали это как c 2, c 8 или c 10 и т. Д.

Премия: 49

Для обработки нечетного ввода, например 13, мы должны фильтровать по нечетным координатам x, а не просто брать каждую вторую строку вывода (потому что теперь индексы могут начинаться либо с четного, либо с нечетного числа). Это обобщение обходится нам в 4 символа:

c=:*:({&' *'@],&":2%(%+/@,))]>(|@j./~2&|#])@i:@<:

Деминимизированная версия:

c =: verb define
  pythag   =. y > | j./~ i:y-1    NB.  r^2 > x^2 + y^2
  squished =. _2 {.\ pythag       NB.  Odd rows only
  piApx    =. (2 * +/ , squished) %  y*y
  (squished { ' *') , ": piApx
)

Улучшения и обобщения благодаря Маршаллу Лохбэму на форумах J.

person Community    schedule 22.07.2013

Python: 118 символов

Довольно простой перенос версии Perl.

r=input()
u=r+r%2
t=0
for i in range(u):n=1+2*int((r*r-(u-1-2*i)**2)**.5);t+=n;print' '*(r-n/2-1),'*'*n
print 2.*t/r/r
person Community    schedule 14.03.2010
comment
Для python2 вы можете просто использовать r=input() - person John La Rooy; 14.03.2010
comment
Пробелы между print и ' ' не нужны - person John La Rooy; 14.03.2010
comment
Ладно, это страшно, сейчас она короче, чем версия Perl. (Я полностью выбросил из головы ввод данных, потому что обычно это так небезопасно ...) - person Nicholas Riley; 14.03.2010

C ++: 169 символов

#include <iostream>
int main(){int i,j,c=0,n;std::cin>>n;for(i=-n;i<=n;i+=2,std::cout<<'\n')for(j=-n;j<=n;j++)std::cout<<(i*i+j*j<=n*n?c++,'*':' ');std::cout<<2.*c/n/n;}

Unminified:

#include <iostream>
int main()
{
    int i,j,c=0,n;
    std::cin>>n;
    for(i=-n;i<=n;i+=2,std::cout<<'\n')
        for(j=-n;j<=n;j++)
            std::cout<<(i*i+j*j<=n*n?c++,'*':' ');
    std::cout<<2.*c/n/n;
}

(Да, при использовании std :: вместо using namespace std используется меньше символов)

Вывод здесь не соответствует тестовым случаям в исходном сообщении, поэтому вот тот, который соответствует (написан для удобства чтения). Считайте это эталонной реализацией (если Poita_ не возражает):

#include <iostream>
using namespace std;

int main()
{
    int i, j, c=0, n;
    cin >> n;
    for(i=-n; i<=n; i++) {
        if (i & 1) {
            for(j=-n; j<=n; j++) {
                if (i*i + j*j <= n*n) {
                    cout << '*';
                    c++;
                } else {
                    cout << ' ';
                }
            }
            cout << '\n';
        }
    }
    cout << 2.0 * c / n / n << '\n';
}

C ++: 168 символов (я считаю правильным вывод)

#include <iostream>
int main(){int i,j,c=0,n;std::cin>>n;for(i=-n|1;i<=n;i+=2,std::cout<<"\n")for(j=-n;j<=n;j++)std::cout<<" *"[i*i+j*j<=n*n&&++c];std::cout<<2.*c/n/n;}
person Community    schedule 13.03.2010
comment
Код зацикливается от -n до n, поэтому для ввода, например, 4 он отображает диаметр 9, а не 7, как показано в тестовых примерах. - person Guffa; 14.03.2010
comment
Требуется ли, чтобы ваш круг соответствовал в точности OP? - person Peter Alexander; 14.03.2010
comment
@Poita_, да звездочки должны точно совпадать для приведенных тестовых случаев. Лишний пробел справа не имеет значения - person John La Rooy; 14.03.2010
comment
Вы можете изменить его на #include <iostream.h>, что в основном #include <iostream> -- using namespace std; для совместимости со старыми компиляторами C ++. - person Earlz; 14.03.2010
comment
что делает оператор & в строке 9 - ›if (i & 1) - person Carlos; 14.03.2010
comment
@Carlos, я не писал этот конкретный бит, но это бинарный оператор AND. Он проверяет, установлен ли последний бит, что эквивалентно выполнению i%2, но выполняется быстрее. Это не совсем быстрее, потому что компилятор все равно это сделает. - person Peter Alexander; 14.03.2010
comment
@Poita_: На самом деле, i% 2 и i & 1 по-разному ведут себя с отрицательными числами. (-1) & 1 равно 1, что мы и хотим здесь. (-1)% 2 - это -1 в моей системе, и это соответствует C99. Таким образом, хотя if (i & 1) и if (i% 2) будут делать то же самое, нужно быть осторожным с if (i% 2 == 1), которое не будет работать, когда i отрицательно. - person Joey Adams; 15.03.2010
comment
Иногда различный приоритет & и % может быть использован для игры в гольф. - person John La Rooy; 15.03.2010
comment
Вы можете сохранить не менее 8 символов, если используете #define o std :: cout ‹<, а затем замените все std :: cout ‹* на o - person Grant Peters; 15.03.2010
comment
Разве метод put () не даст вам на 10 символов меньше? - person Robert Davis; 16.03.2010
comment
@Robert, нет, потому что для этого необходимо включить stdlib.h. - person Peter Alexander; 16.03.2010
comment
@Poita Это зависит от компилятора / компоновщика. GCC 4.3.3 не требует каких-либо включений для использования puts. Я тоже могу сделать это с printf, но на самом деле получаю предупреждение [int printf(const char*)! = Int printf(const char*,...)]. Любая необъявленная c-функция по умолчанию возвращает int и принимает любые аргументы, с которыми она используется. Затем компоновщик должен выяснить реализацию int puts(const char*). Поскольку gcc всегда ссылается на стандартные библиотеки (кроме -nostdlib), это легко. - person KitsuneYMG; 17.03.2010
comment
Что ж, я считаю справедливым то, что код не зависит от особенностей компилятора. - person Peter Alexander; 17.03.2010

PHP: 126 132 138

(на основе решения Guffa C #)

126:

for($y=1-($r=$argv[1]);$y<$r;$y+=2,print"\n")for($x=1-$r;$x<$r;$s+=$i,++$x)echo($i=$x*$x+$y*$y<=$r*$r)?'*':' ';echo$s*2/$r/$r;

132:

for($y=1-($r=$argv[1]);$y<$r;$y+=2){for($x=1-$r;$x<$r;@$s+=$i,++$x)echo($i=$x*$x+$y*$y<=$r*$r?1:0)?'*':' ';echo"\n";}echo$s*2/$r/$r;

138:

for($y=1-($r=$argv[1]);$y<$r;$y+=2){for($x=1-$r;$x<$r;@$s+=$i){$t=$x;echo($i=$t*$x++ +$y*$y<=$r*$r?1:0)?'*':' ';}echo"\n";}echo$s*2/$r/$r;

Текущий полный:

for( $y = 1 - ( $r = $argv[1]); $y < $r; $y += 2, print "\n")
    for( $x = 1-$r; $x < $r; $s += $i, ++$x)
        echo( $i = $x*$x + $y*$y <= $r*$r) ? '*' : ' ';
echo $s*2 /$r /$r;

Может быть без @ перед первым $s, но только с параметром error_reporting, установленным на 0 (выходные данные уведомления портят круг)

person Community    schedule 15.03.2010
comment
что делает / $ r в echo $ s * 2 / $ r / $ r; - person davidosomething; 16.03.2010
comment
ОХХ разделение ... интервал меня сбил с толку, я подумал, что это какое-то стенографирование оператора, которого я никогда не видел - person davidosomething; 16.03.2010

Рубин 1.8.x, 93

r=$_.to_f
q=0
e=r-1
(p(('*'*(n=1|2*(r*r-e*e)**0.5)).center r+r)
q+=n+n
e-=2)while-r<e
p q/r/r

Беги с $ ruby -p piday

person Community    schedule 21.03.2010
comment
Хороший, но он не распечатывает приближение числа пи - person John La Rooy; 22.03.2010
comment
Он не работает в 1.9.1 и выводит двойные кавычки по кругу. - person Mladen Jablanović; 22.03.2010
comment
Программы гольфа не работают на совершенно разных языковых уровнях - это нормально. Сколько Perl или Python c-g работают над каждой версией языка? Однако это интересно, но оказалось, что причина в том, что Integer|Float больше не принудительно использует значение с плавающей запятой в 1.9. - person DigitalRoss; 23.03.2010

APL: 59

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

{⍪(⊂' *'[1+m]),q÷⍨2×+/,m←(2|v)⌿(q←⍵*2)>v∘.+v←2*⍨⍵-⍳1+2×⍵-1}

Диалект - Dyalog APL с источником индекса по умолчанию. Уровень навыка невежественный новичок, поэтому, если какой-либо гуру APL захочет снизить его до 10 символов, будь моим гостем!


Вы можете попробовать его в Интернете на странице Попробуйте APL, просто вставьте его и поставьте после него номер:

   {⍪(⊂' *'[1+m]),q÷⍨2×+/,m←(2|v)⌿(q←⍵*2)>v∘.+v←2*⍨⍵-⍳1+2×⍵-1} 13
      *************
   *******************
  *********************
 ***********************
*************************
*************************
*************************
*************************
 ***********************
  *********************
   *******************
      *************
2.98225
person Community    schedule 24.07.2013
comment
Хотя я не знаю APL, он выглядит красивее, чем J-версия. - person ahala; 25.07.2013
comment
@ahala Действительно. APL красив и концептуально, и эстетически. Я начал изучать J, но меня отключило случайное безумие ASCII. Хороший человек написал интерпретатор APL с открытым исходным кодом для Node.js (npm install apl), и это неплохо. Он вычисляет приведенный выше код с незначительными изменениями (без монадического , 2-го символа). Вы можете найти хорошую документацию по APL на всех сайтах поставщиков, таких как Dyalog. - person Tobia; 25.07.2013

И запись в bash: 181 186 190 символов

for((y=-(r=$1,r/2*2);y<=r;y+=2));do for((x=-r;x<=r;++x));do((x*x+y*y<r*r))&&{((++n));echo -n '*';}||echo -n " ";((x<r))||echo;done;done;((s=1000,p=n*2*s/r/r,a=p/s,b=p%s));echo $a.$b

Запустите, например, bash py.sh 13

person Community    schedule 16.03.2010

Python: 148 символов.

Неудачная (т.е. недостаточно короткая) попытка нарушить правила и жестко закодировать тестовые примеры, как я уже упоминал в ответе на исходное сообщение. Возможно, было проще злоупотребить им, используя более подробный язык:

a=3.0,3.125,3.16
b="1","23","3677","47899"
r=input()
for i in b[r/3]+b[r/3][::-1]:q=1+2*int(i);print ' '*(int(b[r/3][-1])-int(i))+'*'*q
print a[r/5]
person Community    schedule 16.03.2010

bc: 165, 127, 126 символов

На основе версии Python.

r=read()
for(i=-1;r*2>i+=2;scale=6){n=sqrt(2*i*r-i*i)
scale=0
n=1+n/1*2
j=r-n/2
t+=2*n
while(j--)" "
while(n--)"*"
"
"}
t/r/r

(Новая строка после последней строки здесь не может быть пропущена.)

person Community    schedule 16.03.2010
comment
127 символов: r = read (); for (i = 1; i ‹r * 2; scale = 6) {n = sqrt (2 * i ri i); scale = 0; n = 1 + n / 1 * 2; i + = 2; j = rn / 2; t + = 2 * n; while (j--); while (n -) *; }; т / р / р - person Carlos Gutiérrez; 17.03.2010
comment
Единственная проблема здесь в том, что теперь он не работает на 0, но по текущим правилам все в порядке. - person przemoc; 17.03.2010

JavaScript (SpiderMonkey) - 118 символов

Эта версия принимает ввод от стандартного ввода и проходит бонусные тесты.

r=readline()
for(t=0,i=-r;i<r;i++)if(i%2){for(s='',j=-r;j<r;j++){t+=q=i*i+j*j<r*r
s+=q?'*':' '}print(s)}print(t*2/r/r)

Использование: cat 10 | js thisfile.js - предварительный просмотр jsbin добавляет псевдоним для строки печати / чтения, чтобы вы могли просмотреть в браузере

Javascript: 213 163


Обновлено

r=10;m=Math;a=Array;t=0;l=document;for(i=-r;i<r;i+=2){w=m.floor(m.sqrt(r*r-i*i)*2);t+=w*2;l.writeln(a(m.round(r-w/2)).join(' ')+a(w).join('*'));}l.writeln(t/(r*r))

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


r=10;m=Math;a=Array;t=0;s='';for(i=-r;i<r;i++){w=m.floor((m.sqrt(m.pow(r,2)-m.pow(i,2)))*2);t+=w;if(i%2){z=a(m.round(r-w/2)).join(' ')+a(w).join('*');s+=z+'\n';}}document.write('<pre>'+(s+(t/m.pow(r,2)))+'</pre>')

Unminified:

r=10;
m=Math;
a=Array;
t=0;
s='';
for(i=-r;i<r;i++){
    w=m.floor((m.sqrt(m.pow(r,2)-m.pow(i,2)))*2);
    t+=w;
    if(i%2){
    z=a(m.round(r-w/2)).join(' ')+a(w).join('*');
    s+=z+'\n';
    }
}
document.write('<pre>'+(s+(t/m.pow(r,2)))+'</pre>');
person Community    schedule 16.03.2010

Ява: 234

class C{public static void main(String[] a){int x,y,s=0,r=Integer.parseInt(a[0]);for(y=1-r;y<r;y+=2){for(x=1-r;x<r;++x){boolean b=x*x+y*y<=r*r;s+=b?1:0;System.out.print(b?'*':' ');}System.out.println();}System.out.println(s*2d/r/r);}}

Unminified:

class C{
    public static void main(String[] a){
        int x,y,s=0,r=Integer.parseInt(a[0]); 
        for(y=1-r;y<r;y+=2){
            for(x=1-r;x<r;++x) {
                boolean b=x*x+y*y<=r*r;
                s+=b?1:0;
                System.out.print(b?'*':' ');
            }
            System.out.println();
        }
        System.out.println(s*2d/r/r);
    }
}
person Community    schedule 16.03.2010
comment
Возможно, можно было бы сохранить ~ 50 символов, переписав это в scala - person rwyland; 16.04.2012

GAWK: 136, 132, 126, 125 символов

На основе версии Python.

{r=$1
for(i=-1;r*2>i+=2;print""){n=1+int((2*i*r-i*i)**.5)*2
t+=2*n/r/r
printf"%*s",r-n/2,""
while(n--)printf"%c","*"}print t}
person Community    schedule 16.03.2010