我从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 Map 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
##########
# #
# #
# #
# #
# #
# #
# #
# #
##########