我从Codingame那里获得了这一挑战,并且对比我的更好的解决方案感到好奇:
通过标准输入给定宽度,在给定的宽度和长度上绘制一个空心的#号正方形。
例:
5结果
#####
# #
# #
# #
#####
我用python解决了这个问题,所以我对其他python代码特别感兴趣。但是,请随时以所需的任何语言发布您的解决方案。
我从Codingame那里获得了这一挑战,并且对比我的更好的解决方案感到好奇:
通过标准输入给定宽度,在给定的宽度和长度上绘制一个空心的#号正方形。
例:
5结果
#####
# #
# #
# #
#####
我用python解决了这个问题,所以我对其他python代码特别感兴趣。但是,请随时以所需的任何语言发布您的解决方案。
Answers:
码:
NβBββ#
说明:
Nβ # Get input from the command line and store into β
B # Draw a hollow box with...
β # Width β
β # Height β
# # Filled with the character '#'
# Implicitly output the box
N
也可以在表达式中使用它,例如int(input())
在Python中。如果此挑战是“绘制具有给定宽度和高度的空心矩形”,则解决方案可能是BNN#
。
:G\1>&*~35*c
: % Input n implicitly. Push range [1 2 ... n]
% STACK: [1 2 3 4 5]
G % Push n again
% STACK: [1 2 3 4 5], 5
\ % Modulo
% STACK: [1 2 3 4 0]
1> % Does each entry exceed 1?
% STACK: [0 1 1 1 0]
&* % Matrix with all pair-wise products
% STACK: [0 0 0 0 0;
0 1 1 1 0;
0 1 1 1 0;
0 1 1 1 0;
0 0 0 0 0]
~ % Negate
% STACK: [1 1 1 1 1;
1 0 0 0 1;
1 0 0 0 1;
1 0 0 0 1;
1 1 1 1 1]
35* % Multiply by 35
% STACK: [35 35 35 35 35;
35 0 0 0 35;
35 0 0 0 35;
35 0 0 0 35;
35 35 35 35 35]
c % Convert to char. 0 is interpreted as space. Display implicitly
% STACK: ['#####';
'# #';
'# #';
'# #';
'#####']
,ajj"###
,ajj draw a box with height (input) and width (input)
"### with a hash border
#
?
f=lambda n:'#'*n+'\n#%s#'%(' '*(n-2))*(n-2)+'\n'+'#'*n
返回#\n#
时,输入1
打印的55字节版本
def f(n):a=n-2;print'#'*n,'\n#%s#'%(' '*a)*a,'\n'+'#'*n
62字节版本适用于任何输入:
f=lambda n:'#'*n+'\n#%s#'%(' '*(n-2))*(n-2)+('\n'+'#'*n)*(n>1)
f=
除非您使用它,否则您不必说,而您不需要。
MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMMMmoOMMMMoOMoOMoOMoOMoOMoOMoOMoOMoO
MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMMMmoOMMMMoOMoOMoOmoOoomMMM
moOMMMMOOmOomOoMoomoOmoOMOomoomOoMMMmoOMMMMOoMOoMOOmOomOomOomOoMoo
moOmoOMoomoOMMMmoOmoOMMMMOoMOoMOOmOomOomOomOoMoomoOmoOmoOmoOMOomoo
mOomOomOoMoomoOmoOMOomoomOomOomOomOoMoomoOmoOmoOMOOmOoMoomoOMOomoo
在线尝试! 将第二行中的数字更改为任何数字以更改输出。
我在这里使用的COW解释器是用Perl编写的(比这个挑战还新),但是您仍然可以通过在此处输入代码来获得相同的结果。
; Note: [n] means "value stored in the nth block of memory".
MoOMoOMoOMoOMoOMoOMoOMoOMoOMoO ;Stores 10 in [0]. 10 is the code point for carriage return
MMMmoOMMMMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoO ;Stores 32 in [1]. 32 is the code point for whitespace
MMMmoOMMMMoOMoOMoO ;Stores 35 in [2]. 35 is the code point for #
moOoom ;Reads STDIN for an integer, and stores it in [3]
MMMmoOMMM ;Copies [3] into [4]
MOO ;Loop as long as [4] is non-zero
mOomOoMoo ;Navigate to [2] and print the character with that code point
moOmoOMOo ;Navigate to [4] and decrement
moo ;End loop
mOoMMMmoOMMMMOoMOo ;Copy [3] into [4] and decrement [4] twice
MOO ;Loop as long as [4] is non-zero
mOomOomOomOoMoo ;Navigate to [0] and print the character with that code point
moOmoOMoo ;Navigate to [2] and print the character with that code point
moOMMMmoOmoOMMMMOoMOo ;Navigate to [3] and copy it into [5], then decrement [5] twice
MOO ;Loop as long as [5] is non-zero
mOomOomOomOoMoo ;Navigate to [1] and print the character with that code point
moOmoOmoOmoOMOo ;Navigate to [5] and decrement
moo ;End loop
mOomOomOoMoo ;Navigate to [2] and print the character with that code point
moOmoOMOo ;Navigate to [4] and decrement
moo ;End loop
mOomOomOomOoMoo ;Navigate to [0] and print the character with that code point
moOmoOmoO ;Navigate to [3]
MOO ;Loop as long as [3] is non-zero
mOoMoo ;Navigate to [2] and print the character with that code point
moOMOo ;Navigate to [3] and decrement
moo ;End loop
String c(int n){String r="";for(int i=n,j;i-->0;r+="\n")for(j=0;j<n;r+=i*j<1|n-i<2|n-j++<2?"#":" ");return r;}
@OlivierGrégoire节省了1个字节;@cliffroot
节省了2个字节。
基于我的创建交叉正方形答案的派生解决方案。
for(int i=n,j;i-->0;r+="\n")
吗?由于我们不在乎最底线还是最顶线,因此保持该顺序没有任何意义,对吗?
param($n)($z='#'*$n--);,("#$(' '*--$n)#")*$n;$z
-1个字节感谢JohnLBevan
将input $n
,sets设置$z
为$n
哈希标记,$n
后减。将其封装在括号中以将副本放置在管道上。然后使用逗号运算符来创建预递减的阵列$n
的线#
,空格#
。这些留在管道上。然后$z
再次放置在管道上。Write-Output
最后通过隐式输出在元素之间引入了换行符,因此我们免费获得换行符。
由于OP的代码不适用于输入n <= 1
,因此我认为这也意味着我们也不需要支持输入1
。
PS C:\Tools\Scripts\golfing> 2..6|%{"$_";.\draw-a-hollow-square.ps1 $_;""}
2
##
##
3
###
# #
###
4
####
# #
# #
####
5
#####
# #
# #
# #
#####
6
######
# #
# #
# #
# #
######
param($n)($z='#'*$n--);,("#$(' '*--$n)#")*$n;$z
.if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
从中删除括号.if
并使用j
而不是使用-6个字节.if
通过使用f
而不是a .for
来构造字符串的-18个字节。
-12个字节(不是以NULL结尾的字符串),而是将长度传递给 da
输入通过伪寄存器$t0
(例如r $t0 = 5; {above-code}
)传递。
说明:
.if @$t0 *Verify width($t0) at least 1
{ *(registers have unsigned values)
r $t3 = 2000000; *Set $t3 to address where the
*string will be constructed
f @$t3 L@$t0 23; *Put width($t0) '#' at 2000000($t3)
f 2 * @$t3 L@$t0 20; *Put width($t0) ' ' at 4000000(2*$t3)
eb 2 * @$t3 23; *Put '#' on left of ' ' string
eb 2 * @$t3 + @$t0 - 1 23; *Put '#' on right of ' ' string
da @$t3 L@$t0; *Print the top of the box
j 1 < @$t0 *If width($t1) at least 2
'
.for (r $t1 = @$t0 - 2; @$t1; r $t1 = @$t1 - 1) *Loop width($t0)-2 times to...
{
da 2 * @$t3 L@$t0 *...print the sides of the box
};
da @$t3 L@$t0 *Print the bottom of the box
'
}
样本输出:
0:000> r$t0=0
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
0:000> r$t0=1
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
Filled 0x1 bytes
Filled 0x1 bytes
02000000 "#"
0:000> r$t0=2
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
Filled 0x2 bytes
Filled 0x2 bytes
02000000 "##"
02000000 "##"
0:000> r$t0=5
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
Filled 0x5 bytes
Filled 0x5 bytes
02000000 "#####"
04000000 "# #"
04000000 "# #"
04000000 "# #"
02000000 "#####"
@lmis节省了3个字节!
n=>(b='#'[r='repeat'](n))+`
#${' '[r](n-=2)}#`[r](n)+`
`+b
(不处理0
或1
)
对于13个额外的字节(为71个字节),您可以!
n=>n?n-1?(b='#'[r='repeat'](n))+`
#${' '[r](n-=2)}#`[r](n)+`
`+b:'#':''
这些解决方案非常简单:它们进行大量存储,以免重复进行以节省一些字节。如果没有变量,它将变为最小:
n => // Anonymous function definition (Param `n` is the size)
'#'.repeat(n) + // # `n` times to form the top
`
#${' '.repeat(n - 2)}#` // Followed by a newline followed by a hash and `n` - 2 spaces and
// another hash to make one of the middle lines
.repeat(n - 2) + // The above middle lines repeated `n` - 2 times
'#'.repeat(n) // Followed by the top line again
<script type="text/babel">var f=n=>n?n-1?(b='#'[r='repeat'](n))+`\n#${' '[r](n-=2)}#`[r](n)+`\n`+b:'#':'',b,r;function c(){document.getElementById('pre').textContent = f(+document.getElementById('input').value);}</script><input id="input" onkeydown="c();" onkeyup="c();" onchange="c();" onclick="c();" placeholder="Size"><pre id="pre"></pre>
!n?'':n==1?'#':
在函数主体的开头添加额外的15个字节,您可以处理输入0
和1
。
n=>(b='#'[r='repeat'](n))
然后#${" "[r](n-=2)}
等等,通过避免重复来为您节省3个字节repeat
:)
n=int(input())
for x in range(n):
r=list(' '*n);r[0]=r[-1]='#'
if x%(n-1)==0:r='#'*n
print("".join(r))
list(' '*n)
为[' ']*n
。您也可以替换x%(n-1)
为x%~-n
for
块转换为列表推导式,则可以节省20多个字节
int()
并将其放在方括号内print
。
<1
instead of ==0
.
m=input()-2
for c in'#'+' '*m+'#':print'#'+m*c+'#'
Works for n>=2
. Prints each line with a pound sign, n-2
of the appropriate symbol, then another pound sign.
Aliasing the pound symbol gives same length:
m=input()-2;p='#'
for c in p+' '*m+p:print p+m*c+p
Other attempts:
lambda n:'#'*n+('\n#'+' '*(n-2)+'#')*(n-2)+'\n'+'#'*n
lambda n:'#'*n+'\n#%s#'%((n-2)*' ')*(n-2)+'\n'+'#'*n
lambda n:'\n'.join(['#'*n]+['#'+' '*(n-2)+'#']*(n-2)+['#'*n])
n=input();s='#'+' '*(n-2)+'#'
for c in s:print[s,'#'*n][c>' ']
s='##'+' #'*(input()-2)+'##'
for c in s[::2]:print s[c>' '::2]
s='#'+' '*(input()-2)+'#'
for c in s:print s.replace(' ',c)
i,j;f(n){for(i=n;i--;puts(""))for(j=n;j--;putchar(i*j&&i^n-1&&j^n-1?32:35));}
Sneak in a multiply and save a byte...
i,j;f(n){for(i=n;i--;puts(""))for(j=n;j--;putchar(i&&j&&i^n-1&&j^n-1?32:35));}
Also count down j and save a few more...
i,j;f(n){for(i=n;i--;puts(""))for(j=0;j++<n;putchar(i&&j^1&&i^n-1&&j^n?32:35));}
Count down i from n to zero and save a few bytes...
i,j;f(n){for(i=0;i++<n;puts(""))for(j=0;j++<n;putchar(i^1&&j^1&&i^n&&j^n?32:35));}
A bit easier to understand and 1 byte more
i,j;f(n){for(i=0;i++<n;puts(""))for(j=0;j++<n;putchar(i==1|i==n|j==1|j==n?35:32));}
&&
instead of &
?
{n->a="*"*n+"\n";n-=2;print(a+"*${' '*n}*\n"*n+a)}
Works for n > 1. Thanks to @Billywob for a couple of bytes swapping out the array for a matrix.
cat(rbind(b<-'#',cbind(b,matrix(' ',n<-scan()-2,n),b),b,'
'),sep='')
Uses rbind and cbind to put rows and columns of #
's around an n-2 square matrix of spaces. Newlines are bound to the rows as well. The newline in the source is significant. Input is from STDIN
\n
. You could save two bytes by using matrix
instead of array
though.
-20 thanks to @Cyoce and @AlexL.
(defun s(v)(format t"~v,,,vA~%"v #\# #\#)(dotimes(h(- v 2))(format t"~v,,,vA~A~%"(- v 1)#\ #\# #\#))(format t"~v,,,vA"v #\# #\#))
Usage:
* (s 5)
#####
# #
# #
# #
#####
Basically uses format
twice for the top and bottom and a loop for the rows in between. The format call for the top and bottom outputs a line starting with #
and padded to the appropriate width with #
s. The format call for the rows in between works similarly, except the padding is spaces and a #
gets printed at the end of the line.
Note: I'm rather new to Lisp and expect to have a lot of room for improvement on this.
s
? Or do am anonymous function?
dotimes (h (- v 2))
or could it be dotimes(h(- v 2))
?
l#n=l<$[1..n]
f n=unlines$'#'#n:('#':' '#(n-2)++"#")#(n-2)++['#'#n]
Usage example:
Prelude> putStrLn $ f 4
####
# #
# #
####
How it works:
l#n=l<$[1..n] -- helper function that makes n copies of l
'#'#n -- make a string of n copies of #, followed by
#(n-2) -- n-2 copies of
'#':' '#(n-2)++"#" -- # followed by n-2 times spaces, followed by #
['#'#n] -- and a final string with n copies of #
unlines -- join with newlines in-between
,þ%µỊṀ€€ị⁾# Y
,þ%µỊṀ€€ị⁾# Y - Main link: n
þ - outer product with
, - pair: [[[1,1],[2,1],...,[n,1]],[[1,2],[2,2],...,[n,2]], ... ,[[1,n],[2,n],...,[n,n]]]
% - mod n: [[[1,1],[2,1],...,[0,1]],[[1,2],[2,2],...,[0,2]], ... ,[[1,0],[2,0],...,[0,0]]]
µ - monadic chain separation
Ị - abs(z)<=1: [[[1,1],[0,1],...,[1,1]],[[1,0],[0,0],...,[1,0]], ... ,[[1,1],[0,1],...,[1,1]]]
€€ - for each for each
Ṁ - maximum: [[1, 1, ...,1], [1, 0, ..., 1], ... ,[1, 1, ..., 1] ]
ị - index into (1 based)
⁾# - "# ": ["##...#","# ...#", ...,"##...#"]
Y - join with line feeds
15 bytes of code, +1 for -n
flag.
(Y_Xa-2WR'#s)My
Works for input >= 2. Try it online!
First, we define a function y
that takes a string argument, repeats it a-2
times (where a
is the first command-line input), and wraps the result in #
.
Y _ X a-2 WR '#
_ Identity function
X a-2 String-repeated by a-2
WR '# Wrapped in #
Y Yank the resulting function into y
Next, we apply this function twice--once normally, then again with map--to obtain the square as a list of strings:
y M (y s)
(y s) Call function y with s (preinitialized to " ") as argument
y M Map y to each character of the resulting string
For input of 4
, (y s)
results in "# #"
and y M (y s)
in ["####"; "# #"; "# #"; "####"]
. This latter value is then printed, with the -n
flag causing it to be newline-separated.
To get from the ungolfed to the golfed version:
Y
is an operator, which means we can use it in an expression. Instead of Y...
followed by (ys)
, we can just do (Y...s)
.y
; so yM(Y_Xa-2WR'#s)
won't work. Solution: swap the operands of the M
ap operator. As long as one of them is a function and the other is an iterable type, it doesn't matter what order they come in.(let*((d display)(g(λ()(for((i n))(d"#")))))(g)(d"\n")(for((i(- n 2)))(d"#")(for((i(- n 2)))(d" "))(d"#\n"))(g))
Ungolfed:
(define (f n)
(let* ((d display)
(g (λ ()
(for ((i n))
(d "#"))
(d "\n"))))
(g)
(for ((i (- n 2)))
(d "#")
(for ((i (- n 2)))
(d " ") )
(d "#\n"))
(g)))
Testing:
(f 5)
Output:
#####
# #
# #
# #
#####
Pretty darn long for a "golfing" language, but I have forgotten how a lot of it works :P
i_2-_u'#*N+_'#' u*'#N+++u*u
Explanation:
i_2-_u # take input and triplicate, subtracting 2 (5 -> [3,3,5])
'#*N+_ # create the top and bottom rows
'#' u*'#N+++u* # create input - 2 copies of middle rows
u # rotate left 1 to get correct order, implicit output
Golfed:
void F(int n){Console.Write($"{new string('#',n)}\n");for(int i=2;i<n;i++)Console.Write($"#{new string(' ',n-2)}#\n");Console.Write(new string('#',n));}
Ungolfed:
void F(int n)
{
Console.Write($"{new string('#', n)}\n");
for (int i = 2; i < n; i++)
Console.Write($"#{new string(' ', n - 2)}#\n");
Console.Write(new string('#', n));
}
EDIT1: Loop range optimization.
Line split in two for readability:
#N::((var X (repeat "#" N))(print X)(each (seq 3 N) (scope #X::((print (+ "#"
(repeat " " (- N 2)) "#")))))(print X))
Sample usage:
% square.lithp
(
(import "lists")
(def s #N::((var X (repeat "#" N))(print X)(each (seq 3 N) (scope #X::((print (+ "#" (repeat " " (- N 2)) "#")))))(print X)))
(s 10)
)
Output:
$ ./run square.lithp
##########
# #
# #
# #
# #
# #
# #
# #
# #
##########