The task
This challenge is very simple.
Your input is a rectangular 2D array of integers, sized at least 1×1.
It can be taken in any reasonable format.
Your output shall be the input array, but with all entries not on the first or last row or column set to 0
.
It must be in the same format as the input.
For example, if the input array is
67 4 -8 5 13
9 13 42 4 -7
1 1 3 -9 29
16 99 8 77 0
then the correct output is
67 4 -8 5 13
9 0 0 0 -7
1 0 0 0 29
16 99 8 77 0
Rules and scoring
You can write a full program or a function, and functions are allowed to modify the input in place instead of returning it. The lowest byte count wins, and standard loopholes are disallowed.
Test cases
These are formatted as nested lists to make copy-pasting easier.
[[3]] -> [[3]]
[[7,2,8]] -> [[7,2,8]]
[[3],[5],[12],[-6]] -> [[3],[5],[12],[-6]]
[[99,98,97],[88,87,86]] -> [[99,98,97],[88,87,86]]
[[6,7],[8,9],[10,11]] -> [[6,7],[8,9],[10,11]]
[[-1,-2,-3],[1,2,3],[5,5,5]] -> [[-1,-2,-3],[1,0,3],[5,5,5]]
[[67,4,-8,5,13],[9,13,42,4,-7],[1,1,3,-9,29],[16,99,8,77,0]] -> [[67,4,-8,5,13],[9,0,0,0,-7],[1,0,0,0,29],[16,99,8,77,0]]
[[0,1,0,1,0],[1,0,1,0,1],[0,1,0,1,0],[1,0,1,0,1],[0,1,0,1,0]] -> [[0,1,0,1,0],[1,0,0,0,1],[0,0,0,0,0],[1,0,0,0,1],[0,1,0,1,0]]
Leaderboard
Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language. To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
## Language Name, N bytes
If you want to include multiple numbers (e.g. because you've improved your score or you want to list interpreter flags separately), make sure that the actual score is the last number in the header:
## Perl, <s>50</s> 43 + 2 (-p flag) = 45 bytes
You can also make the language name a link which will then show up in the leaderboard snippet:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
var QUESTION_ID=71591,OVERRIDE_USER=32014;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
33 Answers 33
MATL, 9 bytes
0HJ_ht4$(
Input is in the format
[67 4 -8 5 13; 9 13 42 4 -7; 1 1 3 -9 29; 16 99 8 77 0]
EDIT (June 12, 2016): to adapt to changes in the language, the link below has _
replaced by q
.
0 % Push a 0: value that will be assigned into the array
HJ_h % Vector [2, -1j]: this corresponds to index 2:end-1 for rows
t % Duplicate: same index for columns
4$( % Assignment indexing with 4 inputs: array, new value, row and col indices
% Since the first input (array) to this function is currently missing, it's
% implicitly taken at this point from stdin
% Implicitly display stack contents, which is the modified array
-
2\$\begingroup\$ Nice! I knew MATL would be in the running. :D \$\endgroup\$beaker– beaker2016年02月09日 20:56:43 +00:00Commented Feb 9, 2016 at 20:56
Jelly, (削除) 18 (削除ここまで) (削除) 17 (削除ここまで) (削除) 15 (削除ここまで) 9 bytes
0W&ṖZ
ÇÇ^
Try it online! or verify all test cases.
Background
This approach is based on @Sp3000's Jelly answer, specifically on his idea to take advantage of vectorized operations between lists of different lengths.
We start by taking the bitwise AND of 0 and every integer in the first row of the input. Due to automatic vectorization, this can be achieved by taking the bitwise AND of [0] and the input without its last row. 0 is paired with the first row, resulting in a row of zeroes. Since the remaining rows have no counterpart in [0], they are left untouched.
Now we transpose the result, apply the above transformation once again (effectively removing the last column and zeroing out the first), and transpose again.
For the input
67 4 -8 5 13
9 13 42 4 -7
1 1 3 -9 29
16 99 8 77 0
this results in
0 0 0 0
0 13 42 4
0 1 3 -9
Now, we take the bitwise XOR of this result and the original matrix. XORing an integer with itself yields 0. XORing an integer with 0 (or not XORing it at all) yields the same integer. This hollows the matrix out.
How it works
0W&ṖZ Helper link. Argument: M (matrix)
0W Yield [0].
Ṗ Yield M, without its last row.
& Take the bitwise AND of both.
Z Zip the result.
ÇÇ^ Main link. Input: A (matrix)
Ç Call the helper link on A.
Ç Call the helper link on the result.
^ Take the bitwise XOR of the result and A.
Java 7, as a fully named function: 85
void f(int[][]a){for(int i=0,j;++i<a.length-1;)for(j=1;j<a[i].length-1;)a[i][j++]=0;}
You could lambda this down in Java 8 to remove a few bytes, but I don't really do that.
-
\$\begingroup\$ Could you save space by using
Arrays.fill(a[i],1,a[i].length-1,0);
? It's only 36 bytes instead of 37. =) \$\endgroup\$corsiKa– corsiKa2016年02月11日 00:08:39 +00:00Commented Feb 11, 2016 at 0:08 -
\$\begingroup\$ @corsiKa It would be nice, but I'd have to import or fully qualify it :/ \$\endgroup\$Geobits– Geobits2016年02月11日 00:11:13 +00:00Commented Feb 11, 2016 at 0:11
-
\$\begingroup\$ Just out of curiosity, why do you have both loops different? Why not
for(int i=0,j;++i<a.length-1;)for(j=0;++j<a[i].length-1;)a[i][j]=0;
? It doesn't save any bytes, but it's more consistent with both loops being the same. :) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2016年07月18日 12:42:18 +00:00Commented Jul 18, 2016 at 12:42
Mathematica, 27 bytes
(a=#;a[[2;;-2,2;;-2]]=0;a)&
-
2\$\begingroup\$ Impressive. Now, would you please explain it? It looks like you are re-assigning inner cells to zero and the
-2
s denote second the second-last column or row. \$\endgroup\$DavidC– DavidC2016年02月10日 12:53:37 +00:00Commented Feb 10, 2016 at 12:53 -
\$\begingroup\$ How simple it is! \$\endgroup\$njpipeorgan– njpipeorgan2016年02月11日 01:15:05 +00:00Commented Feb 11, 2016 at 1:15
R, (削除) 33 (削除ここまで) 48 bytes
I know, R isn't made for golfing. But it is made for positional indexing... Loading up an example;
a <- matrix(c(67,4,-8,5,13,9,13,42,4,-7,1,1,3,-9,29,16,99,8,77,0), ncol=5, byrow=TRUE)
a
# [,1] [,2] [,3] [,4] [,5]
# [1,] 67 4 -8 5 13
# [2,] 9 13 42 4 -7
# [3,] 1 1 3 -9 29
# [4,] 16 99 8 77 0
Replace the value at any position not on the edge row or column, with 0:
x <- function(a){a[-c(1,nrow(a)),-c(1,ncol(a))]<-0;a}
x(a)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 67 4 -8 5 13
# [2,] 9 0 0 0 -7
# [3,] 1 0 0 0 29
# [4,] 16 99 8 77 0
Also checking a 2-column test:
b <- matrix(c(99,98,97,88,87,86), ncol=2, byrow=TRUE)
b
# [,1] [,2]
#[1,] 99 98
#[2,] 97 88
#[3,] 87 86
x(b)
# [,1] [,2]
#[1,] 99 98
#[2,] 97 88
#[3,] 87 86
Posterity: previous attempt
# a[2:(nrow(a)-1),2:(ncol(a)-1)]<-0 # previous attempt
Testing all examples:
tests <- read.table(text="[[3]] -> [[3]]
[[7,2,8]] -> [[7,2,8]]
[[3],[5],[12],[-6]] -> [[3],[5],[12],[-6]]
[[99,98,97],[88,87,86]] -> [[99,98,97],[88,87,86]]
[[6,7],[8,9],[10,11]] -> [[6,7],[8,9],[10,11]]
[[-1,-2,-3],[1,2,3],[5,5,5]] -> [[-1,-2,-3],[1,0,3],[5,5,5]]
[[67,4,-8,5,13],[9,13,42,4,-7],[1,1,3,-9,29],[16,99,8,77,0]] -> [[67,4,-8,5,13],[9,0,0,0,-7],[1,0,0,0,29],[16,99,8,77,0]]
[[0,1,0,1,0],[1,0,1,0,1],[0,1,0,1,0],[1,0,1,0,1],[0,1,0,1,0]] -> [[0,1,0,1,0],[1,0,0,0,1],[0,0,0,0,0],[1,0,0,0,1],[0,1,0,1,0]]")
tests$cols <- c(1,3,1,3,2,3,5,5)
tests$V1 <- gsub("\\[|\\]","",tests$V1)
tests$V1 <- paste0("c(",tests$V1,")")
tests$V3 <- gsub("\\[|\\]","",tests$V3)
tests$V3 <- paste0("c(",tests$V3,")")
testfn <- function(testno) {
intest <- matrix(eval(parse(text=tests$V1[testno])), ncol=tests$cols[testno], byrow=TRUE)
intest <- x(intest)
outtest <- matrix(eval(parse(text=tests$V3[testno])), ncol=tests$cols[testno], byrow=TRUE)
return(identical(intest, outtest))
}
sapply(seq_len(nrow(tests)), testfn)
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
-
\$\begingroup\$ What happens with a 1 or 2 row or column matrix? \$\endgroup\$mnel– mnel2016年02月10日 06:33:00 +00:00Commented Feb 10, 2016 at 6:33
-
\$\begingroup\$ Good point, first attempt fails the 2-column test and deletes the middle row. I'll update. \$\endgroup\$Jonathan Carroll– Jonathan Carroll2016年02月10日 21:46:44 +00:00Commented Feb 10, 2016 at 21:46
-
1\$\begingroup\$ Welcome to Programming Puzzles & Code Golf! We require all submissions to be either full programs or functions. In this case, your scored code is just a snippet, since it assumes that the variable
a
exists. To be in compliance with our rules, you could make it a function that takes a matrix, likefunction(a){a[-c(1,nrow(a)),-c(1,ncol(a))]=0;a}
for 47 bytes. \$\endgroup\$Alex A.– Alex A.2016年02月11日 06:57:02 +00:00Commented Feb 11, 2016 at 6:57
GNU Sed, 31
- Thanks to @manatwork for saving 4 bytes.
Version 4.2.2 or earlier, prior to this commit (discussion).
Score includes +1 for -r
option.
Input rows are newline separated. Elements on each row are single-line separated.
1n
$n
:
s/ -?\w+ / : /
t
y/:/0/
Explanation
1n # 1st line: print unchanged, then load next line
$n # last line: print unchanged, then load next line (i.e. EOF and stop)
: # unnamed label
s/ -?\w+ / : / # substitute a number in spaces with a `:` in spaces
t # If the above matched, jump back to the label and try again
y/:/0/; # transliterate `:` to `0`
-
1\$\begingroup\$ Oh i see, it's a "fancy" way to get around no lookaheads, and thanks! \$\endgroup\$Andreas Louv– Andreas Louv2016年02月09日 20:43:32 +00:00Commented Feb 9, 2016 at 20:43
-
1\$\begingroup\$ Too many braces:
1n;$n;:;s/ -?\w+ / : /;t;y/:/0/
. \$\endgroup\$manatwork– manatwork2016年02月10日 10:47:02 +00:00Commented Feb 10, 2016 at 10:47 -
1\$\begingroup\$ Can you include the information about the commit that makes your answer work in a quote block, the site is really slow and takes 1 minute to fully load \$\endgroup\$Ferrybig– Ferrybig2016年02月11日 14:28:53 +00:00Commented Feb 11, 2016 at 14:28
-
\$\begingroup\$ @manatwork Thanks - saved 4 bytes! \$\endgroup\$Digital Trauma– Digital Trauma2016年02月11日 16:12:28 +00:00Commented Feb 11, 2016 at 16:12
-
\$\begingroup\$ @Ferrybig Added another link to the dev discussion on this topic. \$\endgroup\$Digital Trauma– Digital Trauma2016年02月11日 16:13:02 +00:00Commented Feb 11, 2016 at 16:13
Octave, 34 bytes
function h(M) M(2:end-1,2:end-1)=0
Note that the input requires semicolons to separate array rows:
h([[3];[5];[12];[-6]])
Explanation:
Octave (and MATLAB) array indices are 1-based. Specifying a range of Array(1:end)
will give you all elements of the (one-dimensional, in this example) array. Array(2:end-1)
will give you all of the elements except the first and last.
M(2:end-1,2:end-1)=0
sets to 0
all elements not in the first or last row or column:
>> A = [[-1,-2,-3];[1,2,3];[5,5,5]]
A =
-1 -2 -3
1 2 3
5 5 5
>> h(A)
M =
-1 -2 -3
1 0 3
5 5 5
If one of the dimensions is less than or equal to 2, the range end-1
is less than 2, therefore the end of the range (2:end-1)
is less than the beginning. In this case, Octave ignores the range and does nothing. This is analogous to the for
loop:
for (int i=2; i < 2; i++) {...}
The stop condition is true on the first iteration, so we fall out of the loop.
>> A = [[6,7];[8,9];[10,11]]
A =
6 7
8 9
10 11
>> h(A)
M =
6 7
8 9
10 11
Jelly, 12 bytes
×ばつ
I think this works, still wrapping my head around Jelly. Try it online!
(Thanks to @Dennis for -2 bytes)
Works by multiplying the input array by an arrays of 1s and 0s one dimension smaller each way. For example, for [[67,4,-8,5,13],[9,13,42,4,-7],[1,1,3,-9,29],[16,99,8,77,0]]
we multiply element-wise by
1 1 1 1
1 0 0 0
1 0 0 0
Full explanation
[Helper link - argument is a matrix]
Z Zip
ṖṖ Pop last two elements, or [:-2]
1;\€ Append a 1 in front of every row
[Main link]
¬ Not, turning 0s to 1s and everything else to 0s. Even though some zeroes
turn into 1s, it's fine because we multiply element-wise at the end,
and 0*1 = 0
ÇÇ Perform helper link twice
×ばつ Multiply element-wise
Mathematica (削除) 81 (削除ここまで) 76 bytes
(d=Dimensions@m;q=MemberQ;m Boole@Array[{1,d[[1]]}~q~#||{1,d[[2]]}~q~#2&,d])&
How it works
Assume that the input array is stored in m
.
The dimensions of m
are {4,5}`
(m={{67,4,-8,5,13}, {9,13,42,4,-7}, {1,1,3,-9,29}, {16,99,8,77,0}})//MatrixForm
Each cell in the following array, a
, is True if the cell is either in the first or (||
) in last row or in the first or last column; otherwise it is False.
(d=Dimensions@m;a=Array[MemberQ[{1,d[[1]]},#]||MemberQ[{1,d[[2]]},#2]&,d])&[m]//MatrixForm
Applying the function Boole
to the array converts True to 1 and False to 0.
b = Boole[a]
Multiply the matrix m
by b
. This multiplies each cell in m by the corresponding cell in b.
m b
-
\$\begingroup\$ You can use
||
as your OR to save a couple of bytes, and I can see a few other bytes you can save too! \$\endgroup\$A Simmons– A Simmons2016年02月09日 21:15:28 +00:00Commented Feb 9, 2016 at 21:15 -
\$\begingroup\$ A Simmons, Thanks for the suggestion. \$\endgroup\$DavidC– DavidC2016年02月09日 21:32:59 +00:00Commented Feb 9, 2016 at 21:32
-
\$\begingroup\$ #-Unitize@ArrayFilter[Det,Array[Norm@*List,Dimensions@#],1]#& \$\endgroup\$njpipeorgan– njpipeorgan2016年02月09日 23:48:19 +00:00Commented Feb 9, 2016 at 23:48
-
\$\begingroup\$ @njpipeorgan, I suggest you submit it. (And hopefully explain how it works!) \$\endgroup\$DavidC– DavidC2016年02月10日 04:40:29 +00:00Commented Feb 10, 2016 at 4:40
-
\$\begingroup\$ @DavidC I have posted my answer \$\endgroup\$njpipeorgan– njpipeorgan2016年02月10日 06:27:01 +00:00Commented Feb 10, 2016 at 6:27
ES6, (削除) 52 (削除ここまで) (削除) 48 (削除ここまで) 46 bytes
f=a=>a.map((b,i)=>i&&a[i+1]+.5?b.map?f(b):0:b)
Edit: Saved 4 bytes thanks to @user81655. Saved a further 2 bytes thanks to @ETHproductions.
-
\$\begingroup\$ Clever! Here's a very similar approach without
g
which saves a few bytes:f=a=>a.map((b,i)=>i&&a[i+1]!=a.x?b.map?f(b):0:b)
\$\endgroup\$user81655– user816552016年02月10日 04:35:51 +00:00Commented Feb 10, 2016 at 4:35 -
\$\begingroup\$ Nice job! I count 48 bytes (perhaps you forgot to count the
f=
), but you can get it down to 46:f=a=>a.map((b,i)=>i&&a[i+1]+.5?b.map?f(b):0:b)
\$\endgroup\$ETHproductions– ETHproductions2016年02月10日 17:56:07 +00:00Commented Feb 10, 2016 at 17:56 -
1\$\begingroup\$ @ETHproductions Yes, I did forget to count the
f=
. Also I'm slightly surprised+.5
works but I see it does a string addition in the other call. \$\endgroup\$Neil– Neil2016年02月10日 20:10:07 +00:00Commented Feb 10, 2016 at 20:10
Javascript, (削除) 62 (削除ここまで) (削除) 59 (削除ここまで) 56 bytes
s=>s.replace(/(^.*|\n\s*\S+)|\S+(?= .*\n)/g,(a,b)=>b||0)
This approach expects an string as argument. You can see what the regex do here: https://regex101.com/r/kC6xA8/3
Mathematica, 55 bytes
#-Unitize@ArrayFilter[Det,Power~Array~Dimensions@#,1]#&
Test case
%[RandomInteger[9,{5,5}]]
(*
{{8,8,3,6,5},
{7,0,0,0,4},
{2,0,0,0,7},
{3,0,0,0,5},
{8,6,1,0,8}}
*)
Explanation
The main idea of this answer is the same as DavidC's answer (first construct a mask matrix, and then multiply it to the original matrix), but the construction of mask matrix is different.
ArrayFilter[f,list,r]
maps f
onto every element of list
within a radius of r
.
ArrayFilter[f,{1,2,3,4,5},1]
(* { f[{1,1,2}], f[{1,2,3}], f[{2,3,4}], f[{3,4,5}], f[{4,5,5}] } *)
Note that boundary elements are duplicated where there are insufficient neighbors. When list
is of 2-dimensions, this feature works well together with Det
to give the desired result, since duplicated columns or rows on four boundaries vanish the determinants.
ArrayFilter[Det,Power~Array~{4,4},1]
(*
{{0, 0, 0, 0},
{0, 12, 72, 0},
{0, 48, 1152, 0},
{0, 0, 0, 0}}
*)
where Power~Array~{4,4}
guarantees the determinants on inner positions to be non-zero. And
1-Unitize@%
(*
{{1,1,1,1},
{1,0,0,1},
{1,0,0,1},
{1,1,1,1}}
*)
gives the mask matrix.
Python, 50 bytes
def f(a):
for l in a[1:-1]:l[1:-1]=[0]*(len(l)-2)
Accepts a list of lists, and modifies it in place. Python's slice syntax is not inconvenient for this task.
I learned that multiplying a list by a negative number results in an empty list, which allows the above code to work on small inputs.
Julia, (削除) 50 (削除ここまで) 35 bytes
A->A[2:size(A,1)-1,2:size(A,2)-1]=0
This is an anonymous function that accepts an array and modifies it in place. To call it, assign it to a variable.
The approach here is quite simple: For the n by m input array A, we assign Aij = 0 for all i = 2, ..., n-1 and j = 2, ..., m-1 by constructing ranges of indices. The ranges may be empty, like if n or m = 1, in which case no replacement is done.
Saved 15 bytes thanks to Dennis!
C, 62 bytes
y;f(a,b,c)int **a;{for(b--;b-->1;)for(y=1;y<c-1;)a[b][y++]=0;}
Hope it's ok to take in array length/width as parameters. I played around with memset/bzero a little bit, but multiplying by sizeof(int)
drastically increased the code size.
EDIT: 55 bytes if we can further bend the rules and store our array as characters since the input is only a single digit each.
x;
#define f(a,b,c) for(x=1;x<b-1;)bzero(a[x++]+1,c-2);
EDIT: Thanks Washington Guedes for the tip!
-
\$\begingroup\$ Did you literally try to multiply by
sizeof(int)
? You could use4
instead... \$\endgroup\$anatolyg– anatolyg2016年02月09日 22:13:05 +00:00Commented Feb 9, 2016 at 22:13 -
\$\begingroup\$
sizeof(int) != 4
on my machine :P \$\endgroup\$Josh– Josh2016年02月09日 22:16:56 +00:00Commented Feb 9, 2016 at 22:16 -
\$\begingroup\$ I bet it's still a single-digit number, which you can use. \$\endgroup\$anatolyg– anatolyg2016年02月09日 22:20:37 +00:00Commented Feb 9, 2016 at 22:20
-
\$\begingroup\$ I meant at that point I could just decide it's an array of chars rather than ints, since the problem only uses single digit numbers. Just depends how far we want to bend the rules. \$\endgroup\$Josh– Josh2016年02月09日 22:26:13 +00:00Commented Feb 9, 2016 at 22:26
-
\$\begingroup\$ Thanks! Now I also get to use the aloof
-->
operator ;) \$\endgroup\$Josh– Josh2016年02月12日 19:05:04 +00:00Commented Feb 12, 2016 at 19:05
Perl 6, 28 bytes
{.[1..*-2]»[1..*-2] »=»0}
This modifies the input in-place
Usage
my @test-cases = (
[[3],] => [[3],],
[[7,2,8],] => [[7,2,8],],
[[3],[5],[12],[-6]] => [[3],[5],[12],[-6]],
[[99,98,97],[88,87,86]] => [[99,98,97],[88,87,86]],
[[6,7],[8,9],[10,11]] => [[6,7],[8,9],[10,11]],
[[ -1,-2,-3],[1,2,3],[5,5,5]] => [[ -1,-2,-3],[1,0,3],[5,5,5]],
[[67,4,-8,5,13],[9,13,42,4,-7],[1,1,3,-9,29],[16,99,8,77,0]] => [[67,4,-8,5,13],[9,0,0,0,-7],[1,0,0,0,29],[16,99,8,77,0]],
[[0,1,0,1,0],[1,0,1,0,1],[0,1,0,1,0],[1,0,1,0,1],[0,1,0,1,0]] => [[0,1,0,1,0],[1,0,0,0,1],[0,0,0,0,0],[1,0,0,0,1],[0,1,0,1,0]],
);
use Test;
plan +@test-cases;
for @test-cases {
my $k = .key;
{.[1..*-2]»[1..*-2] »=»0}( $k ); # <==
ok $k eqv .value
}
1..8
ok 1 -
ok 2 -
ok 3 -
ok 4 -
ok 5 -
ok 6 -
ok 7 -
ok 8 -
-
\$\begingroup\$
{.[1..*-2]»[1..*-2]X=0}
saves 2 bytes \$\endgroup\$raiph– raiph2016年02月10日 06:58:11 +00:00Commented Feb 10, 2016 at 6:58 -
\$\begingroup\$ @raiph it doesn't appear to work for the last two cases \$\endgroup\$Brad Gilbert b2gills– Brad Gilbert b2gills2016年02月15日 01:30:16 +00:00Commented Feb 15, 2016 at 1:30
JavaScript ES6, (削除) 69 (削除ここまで) (削除) 66 (削除ここまで) 57 bytes
Y=>Y.map((X,y)=>X.map((N,x)=>x*y&&X[x+1]+.5&&Y[y+1]?0:N))
How it works
This solution maps through each y-index y
and x-index x
in the input and decides whether or not to throw it out based on these two indices. There are four cases which we need to keep:
x
is 0y
is 0x
equals the length of the inner array, minus 1y
equals the length of the outer array, minus 1
We can take care of the first two with a little multiplication: x*y
returns 0
iff either x
or y
are 0, and a positive integer otherwise. Now for the third: we could check if X.length>x+1
, but that takes a lot of bytes. Another way to do this is to check if the item ahead is falsy, namely undefined
, which is what you get when trying to access a non-existent item. However, this also matches if the next item is 0
, so we add 0.5 to make sure that doesn't happen:
1 + 0.5 = 1.5 (truthy)
0 + 0.5 = 0.5 (truthy)
-1 + 0.5 = -0.5 (truthy)
undefined + 0.5 = NaN (falsy)
Finally, the fourth point: since the outer array has only arrays inside, and any array is truthy, we can just check Y[y+1]
. Now with ?0:N
, we convert it to 0
if all of the above turned out truthy; N
otherwise. And that's it!
Retina, (削除) 31 24 (削除ここまで) 22
(?<=¶.+ )\S+(?= .*¶)
0
Saved 2 bytes thanks to randomra
There is probably a better way to do it, as this is just a pretty basic multi-line replacement. Essentially we find each number that is preceded by a newline, some number of characters and a space, and is immediately followed by a space and then and is eventually followed by a newline. These numbers are then all replaced with 0
.
This will not preserve column padding, but I don't think that's a problem.
Java 8, as a lambda function: (削除) 82 (削除ここまで) (削除) 83 (削除ここまで) 95 chars/bytes
Lambda Signature: int[][] -> (void)
(i.e. Consumer<int[][]>
)
(a)->{int[]v={1,1};while(++v[0]<a.length){while(++v[1]<a[0].length)a[v[0]-1][v[1]-1]=0;v[1]=1}}
EDIT Made a mistake, I thought that a[x, y] was the xth row and the yth col. Clearly it should be a[x][y] though!
EDIT I forgot to test the code, and I need to set the column back to zero every time inside the loop, +12 bytes. :/
Haskell, (削除) 59 (削除ここまで) 58 bytes
k _[x]=[x]
k f(x:y)=x:(f<$>init y)++[last y]
f=k(k(\_->0))
Expanded
onInner :: (a -> a) -> [a] -> [a]
onInner _ [x] = [x]
onInner f (x:xs) = x : map f (init xs) ++ [last xs]
hollowOut :: [[Int]] -> [[Int]]
hollowOut =
onInner -- leave first and last line alone
(onInner -- leave first and last entry per line
(const 0) -- replace entries by 0
)
-
\$\begingroup\$ You should be able to turn
++[last y]
into:(last y)
or:last y
\$\endgroup\$HEGX64– HEGX642016年02月10日 12:08:12 +00:00Commented Feb 10, 2016 at 12:08 -
\$\begingroup\$ @HEGX64: No, wrong type.
x : map f (...)
is already of type[a]
, andlast y
has typea
, whereas(:) :: a -> [a] -> [a]
. Adding an element at the end of a list in Haskell kind of sucks, since those lists are single-linked forward lists. \$\endgroup\$Zeta– Zeta2016年02月10日 12:49:17 +00:00Commented Feb 10, 2016 at 12:49 -
\$\begingroup\$ Opps. I knew I should have tried it myself before posting :) \$\endgroup\$HEGX64– HEGX642016年02月10日 13:19:44 +00:00Commented Feb 10, 2016 at 13:19
-
1\$\begingroup\$ You can turn
k
into an infix operator, let's say#
and flip the arguments to save one byte:[x]#_=...
,(x:y)#f=...
,f=(#(# \_->0))
and you can drop the name of your main function, i.e.f=
for another two bytes. \$\endgroup\$nimi– nimi2016年02月10日 18:27:52 +00:00Commented Feb 10, 2016 at 18:27
Pyth, 18 bytes
Qjbm:dSttld0P.Qe.Q
Explanation
- autoassign Q=eval(input())
- autoassign .Q = map(eval, rest_of_input)
Q - imp_print(Q)
m P.Q - [V for d in .Q[:-1]]
Sttld - range(1, len(d)-2+1)
:d 0 - assign_indexes(d, ^, 0)
jb - "\n".join(^)
e.Q - imp_print(.Q[-1])
Input arrays are separated by newlines
Groovy, 70 bytes
This isn't very creative, but it's short!
g={a->for(i=1;i<a.size()-1;i++)for(j=1;j<a[i].size()-1;)a[i][j++]=0;a}
Explanation
Closure with one arg
g={a->
Iterate over the inner array, skipping the first and last elements
for(i=1;i<a.size()-1;i++)
Iterate over middle items in the inner array
for(j=1;j<a[i].size()-1;)
Set the elements to 0
and return a
a[i][j++]=0;a}
Tests
assert g([[3]]) == [[3]]
assert g([[7, 2, 8]]) == [[7, 2, 8]]
assert g([[3], [5], [12], [-6]]) == [[3], [5], [12], [-6]]
assert g([[99, 98, 97], [88, 87, 86]]) == [[99, 98, 97], [88, 87, 86]]
assert g([[6, 7], [8, 9], [10, 11]]) == [[6, 7], [8, 9], [10, 11]]
assert g([[-1, -2, -3], [1, 2, 3], [5, 5, 5]]) == [[-1, -2, -3], [1, 0, 3], [5, 5, 5]]
assert g([[67, 4, -8, 5, 13], [9, 13, 42, 4, -7], [1, 1, 3, -9, 29], [16, 99, 8, 77, 0]]) == [[67, 4, -8, 5, 13], [9, 0, 0, 0, -7], [1, 0, 0, 0, 29], [16, 99, 8, 77, 0]]
assert g([[0, 1, 0, 1, 0], [1, 0, 1, 0, 1], [0, 1, 0, 1, 0], [1, 0, 1, 0, 1], [0, 1, 0, 1, 0]]) == [[0, 1, 0, 1, 0], [1, 0, 0, 0, 1], [0, 0, 0, 0, 0], [1, 0, 0, 0, 1], [0, 1, 0, 1, 0]]
R, (削除) 71 (削除ここまで) (削除) 64 (削除ここまで) 57 Bytes
function(m){if(all((y<-dim(m)-1)>1))m[2:y[1],2:y[2]]=0;m}
edit -7 bytes by explicitly dealing with <2-row or <2-column matrices explicitly edit2 -7 bytes by assigning dimensions of matrix while checking the size
C++, (削除) 80 (削除ここまで) 79 bytes
Expects the array as int**
with given sizes n
and k
:
void p(int**c,int n,int k){for(int j,i=1;1+i<n;++i)for(j=1;j+1<k;)c[i][j++]=0;}
An alternative that works for any type that has size()
and value_type & operator[](int)
(98 bytes):
template<class C>void p(C&c){for(int j,i=1;1+i<c.size();++i)for(j=1;j+1<c[i].size();)c[i][j++]=0;}
Expanded version
template <class Container>
void hollowOut(Container & ctn){
const auto size = ctn.size();
for(typename Container::size_type i = 1; i + 1 < size; ++i) {
const auto inner_size = ctn[i].size();
for(decltype(inner_size) j = 1; j + 1 < inner_size; ++j) {
ctn[i][j] = 0;
}
}
}
-
\$\begingroup\$ Seem like adding matrix dimensions to the input is a standard loophole \$\endgroup\$aross– aross2016年02月11日 16:30:39 +00:00Commented Feb 11, 2016 at 16:30
PHP, (削除) 82 (削除ここまで) (削除) 81 (削除ここまで) (削除) 80 (削除ここまで) 71 bytes
function(&$z){for(;$z[++$i+1];)for(;0 .$z[0][++$$i+1];)$z[$i][$$i]=0;};
Run like this:
php -r '$f = function(&$z){for(;$z[++$i+1];)for(;0 .$z[0][++$$i+1];)$z[$i][$$i]=0;}; $z=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]; $f($z); print_r($z);'
- Saved a byte by assuming constant size rows (thx to manatwork)
- Saved a byte by making it an anonymous function
- Saved 7 bytes by using truthyness of next array item, preventing calls to
count
, which is a way too long name for codegolf
-
\$\begingroup\$ As processing a matrix, all sub-arrays should be the same length. So in the inner
for
is safe to always iterate up tocount($z[0])-1
to spare 1 character. \$\endgroup\$manatwork– manatwork2016年02月11日 09:34:40 +00:00Commented Feb 11, 2016 at 9:34
APL, (削除) 17 bytes (削除ここまで) 15 bytes
×ばつ(⌽∨⊖)1∊ ̈⍳⍴⍵}
How it works
⍳⍴⍵
generates a 2D array where all the cells contain the coordinates of all the cells of the argument.1∊ ̈
searches in each such cell if there's a 1 and returns a 1 if so, or 0 otherwise. This builds a matrix where the first row and the first column are 1s and all the rest are 0.(⌽∨⊖)
combines with logical "or" two version of the matrix, one reversed along the first and one reversed along the last axis.×ばつ
is the standard multiplication.
-
\$\begingroup\$ You can substitute (⊣∨⊖∘⌽) with (⊖∨⌽), two bytes less \$\endgroup\$Moris Zucca– Moris Zucca2016年07月01日 08:18:38 +00:00Commented Jul 1, 2016 at 8:18
-
\$\begingroup\$ Brilliant! Let me do that! \$\endgroup\$lstefano– lstefano2016年07月18日 08:11:26 +00:00Commented Jul 18, 2016 at 8:11
APL (Dyalog Classic), 12 bytes
⊢-(⍉0⍪1↓⌽)⍣4
⍉⌽⍵
is normally rotation (reverse horizontally and transpose)
here we combine it with 0⍪1↓⍵
which replaces the first row with zeroes (drop one row, then concatenate 0 on top) into a single train: ⍉0⍪1↓⌽
⍣4
repeats 4 times
⊢-
subtracts from the original matrix
05AB1E, 11 bytes
4FøεNĀ*}R}^
Try it online or verify all test cases.
Explanation:
4F } # Loop 4 times:
ø # Transpose/zip; swapping rows/columns
ε } # Map over the matrix (takes the input implicitly in the first iteration)
NĀ # Trutify the index (0 remains 0; everything else becomes 1)
* # Multiply all values in the current row of the matrix with it
R # Reverse the matrix
^ # Bitwise-XOR the resulting matrix with the (implicit) input-matrix
# (and output implicitly)
Example run:
Input: [[67,4,-8,5,13],[9,13,42,4,-7],[1,1,3,-9,29],[16,99,8,77,0]]
Iteration 1:
Zip: [[67,9,1,16],[4,13,1,99],[-8,42,3,8],[5,4,-9,77],[13,-7,29,0]]
Map: [[0,0,0,0],[4,13,1,99],[-8,42,3,8],[5,4,-9,77],[13,-7,29,0]]
Reverse: [[13,-7,29,0],[5,4,-9,77],[-8,42,3,8],[4,13,1,99],[0,0,0,0]]
Iteration 2:
Zip: [[13,5,-8,4,0],[-7,4,42,13,0],[29,-9,3,1,0],[0,77,8,99,0]]
Map: [[0,0,0,0,0],[-7,4,42,13,0],[29,-9,3,1,0],[0,77,8,99,0]]
Reverse: [[0,77,8,99,0],[29,-9,3,1,0],[-7,4,42,13,0],[0,0,0,0,0]]
Iteration 3:
Zip: [[0,29,-7,0],[77,-9,4,0],[8,3,42,0],[99,1,13,0],[0,0,0,0]]
Map: [[0,0,0,0],[77,-9,4,0],[8,3,42,0],[99,1,13,0],[0,0,0,0]]
Reverse: [[0,0,0,0],[99,1,13,0],[8,3,42,0],[77,-9,4,0],[0,0,0,0]]
Iteration 4:
Zip: [[0,99,8,77,0],[0,1,3,-9,0],[0,13,42,4,0],[0,0,0,0,0]]
Map: [[0,0,0,0,0],[0,1,3,-9,0],[0,13,42,4,0],[0,0,0,0,0]]
Reverse: [[0,0,0,0,0],[0,13,42,4,0],[0,1,3,-9,0],[0,0,0,0,0]]
Bitwise-XOR: [[67,4,-8,5,13],[9,0,0,0,-7],[1,0,0,0,29],[16,99,8,77,0]]
Perl, 34 + 2 = 36 bytes
next if$.==1||eof;s/ .+?(?= )/ 0/g
Requires the -p
flag:
$ perl -pE'next if$.==1||eof;s/ .+?(?= )/ 0/g' <<< $'1 2 3\n4 5 6\n7 8 9'
1 2 3
4 0 6
7 8 9
How it works:
# '-p' Read each line into `$_` and auto prints
next if$.==1||eof; # `$.` is set to to the current line in file (1, 2, ..., n)
# and `eof` is true if its the last line
s/ .+?(?= )/ 0/g
Lua, 69 bytes
function f(a)for i=2,#a-1 do
for o=2,#a[i]-1 do
a[i][o]=0
end
end end
If only I had curly braces instead of dos and ends...