Don't you hate it when you want to copy-paste a list of numbers (vector, array ...), from one program to another, but the format you have the numbers on doesn't match the format you need it on?
For instance, in MATLAB you may have a space separated list like this:
[1 2 3 4 5] (you can also have it comma separated, but that's not the point)
In Python you would need to insert commas to make that list a valid input, so you'd have to convert it to
[1, 2, 3, 4, 5]
to make it work. In C++ you might want something like:
{16,2,77,29}
and so on.
To simplify everyone's life, let's create a list converter, that takes a list on any format*, and outputs a list on another specified format.
The valid brackets are:
[list]
{list}
(list)
<list>
list (no surrounding brackets)
The valid delimiters are:
a,b,c
a;b;c
a b c
a, b, c <-- Several spaces. Must only be supported as input.
a; b; c <-- Several spaces. Must only be supported as input.
a b c <-- Several spaces. Must only be supported as input.
Note, the input can have any number of spaces between the numbers, but the output can choose to have zero spaces (if ,
or ;
is used as delimiter), or a single space (if it's space-delimited).
In addition to the input list, there will be a string (or two characters) that defines the output format. The format string will first be the opening bracket type (only), [
, (
, <
, {
or (the last one is a single space used when there is no surrounding bracket). The bracket type will be followed by the delimiter type, ,
, ;
or (the last one is a single space). The two input format characters must be taken as a single argument (string or two consecutive characters) in the order described above.
Some examples of format strings:
[, <-- Output format: [a,b,c]
{; <-- Output format: {a;b;c}
<-- Two spaces, output list has format: a b c
Rules:
- The output can't have leading spaces
- The output can have trailing spaces and a newline
- The output should only be the list of numbers, not
ans =
or similar
- The output should only be the list of numbers, not
- The input will be a list of integer or decimal numbers (both positive and negative (and zero)), and a string of two characters
- If the input consist of only integers, the output list should have only integers. If the input list consist of integers and decimal numbers, all output numbers can be decimal numbers. (It's optional to keep the integers as integers)
- The maximum number of digits after the decimal point that must be supported are 3.
- The input will be two arguments. I.e. the numbers are in one argument, and the format string is a single argument.
- The code can be a program or function
- The input can be function argument or STDIN
Some examples:
1 2 3 4
[,
[1,2,3,4]
<1; 2; 3>
; <-- Space + semicolon
1;2;3
not valid: 1.000;2.000;3.000 (Input is only integers => Output must be integers)
{-1.3, 3.4, 4, 5.55555555}
[,
[-1.300,3.400,4.000,5.556] (5.555 is also valid. Rounding is optional)
also valid: [-1.3,3.4,4,5.55555555]
The shortest code in bytes win. As always, the winner will be selected one week from the day the challenge was posted. Answers that are posted later can still win if they are shorter than the current winner.
Leaderboard
The Stack Snippet at the bottom of this post generates the catalog from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
## Language Name, N bytes
where N
is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
## Ruby, <s>104</s> <s>101</s> 96 bytes
If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:
## Perl, 43 + 2 (-p flag) = 45 bytes
You can also make the language name a link which will then show up in the snippet:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
var QUESTION_ID=66345,OVERRIDE_USER=44713;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>
11 Answers 11
JavaScript (ES6), 75 (削除) 82 (削除ここまで)
As an anonymous function
Edit: 2 byte saved thx @user81655 (and 5 more just reviewing it)
(l,[a,b])=>a.trim()+l.match(/[-\d.]+/g).join(b)+']})> '['[{(< '.indexOf(a)]
Test snippet
F=(l,[a,b])=>a.trim()+l.match(/[-\d.]+/g).join(b)+']})> '['[{(< '.indexOf(a)]
// Test
console.log=x=>O.innerHTML+=x+'\n'
// default test suite
t=[['1 2 3 4','[,'],['<1; 2; 3>',' ;'],['{-1.3, 3.4, 4, 5.55555555}','[,']]
t.forEach(t=>console.log(t[0]+' *'+t[1]+'* '+F(t[0],t[1])))
function test() { console.log(P1.value+' *'+P2.value+'* '+F(P1.value,P2.value)) }
#P1 { width: 10em }
#P2 { width: 2em }
P1<input id=P1>
P2<input id=P2>
<button onclick="test()">-></button>
<pre id=O></pre>
CJam, (削除) 35 (削除ここまで) 34 bytes
l(S-l"{[<(,}]>);":BSerS%@*1$B5/~er
Expects the format on the first line and the list on the second.
Explanation
l e# Read the format line.
( e# Pull off the first character, which is the opening bracket.
S- e# Set complement with a space, which leaves brackets unchanged and turns a space
e# into an empty string.
l e# Read the list.
"{[<(,}]>);":B
e# Push this string which contains all the characters in the list we want to ignore.
Ser e# Replace each occurrence of one of them with a space.
S% e# Split the string around runs of spaces, to get the numbers.
@ e# Pull up the the delimiter string.
* e# Join the numbers in the list with that character.
1$ e# Copy the opening bracket (which may be an empty string).
B5/ e# Push B again and split it into chunks of 5: ["{[<(," "}]>);"]
~ e# Unwrap the array to leave both chunks on the stack.
er e# Use them for transliteration, to turn the opening bracket into a closing one.
Pyth, 33 bytes
rjjezrXwJ"<>[] {}(),;"d7@c6JChz6
Try it online: Demonstration or Test Suite
Explanation:
J"<>[] {}(),;" assign this string to J
rjjezrXwJd7@c6JChz6 implicit: z = first input string, e.g. "[;"
w read another string from input (the list of numbers)
X Jd replace every char of ^ that appears in J with a space
r 7 parse ^ (the string of numbers and spaces) into a list
jez put z[1] (the separator symbol) between the numbers
c6J split J into 6 pieces ["<>", "[]", " ", "{}", "()", ",;"]
Chz ASCII-value of z[0] (opening bracket symbol)
@ take the correspondent (mod 6) brackets from the list
j and put the numbers between these brackets
r 7 remove leading and trailing spaces
PowerShell, (削除) 108 (削除ここまで) (削除) 100 (削除ここまで) (削除) 95 (削除ここまで) 85 Bytes
$i,$z=$args;($z[0]+($i-split'[^\d.-]+'-ne''-join$z[1])+' }) >]'[($z[0]-32)%6]).Trim()
(see revision history for previous versions)
Golfed another 15 bytes by removing $b
and $s
variables and changing parens on the inner string.
This takes input as two strings and stores them into $i
and $z
, then we construct a new output string. The inner parens -split
s $i
with a regex to select only numeric digits, then -join
s back together with the requested delimiter. We concatenate that with the first character of the delimiter input (e.g., [
) and close it with indexing into a string based on the ASCII value of the first character and some formulation trickery. The outer .Trim()
removes any leading or trailing spaces.
-
\$\begingroup\$ I think you could replace your closing bracket expression
"]})>"["[{(< ".IndexOf($b[0])]
with something like' }) >]'[($b[0]-32)%6]
. The($b[0]-32)%6
gives you0,2,4,5,1
for opening bracket characters, which you can use to index into the closing bracket string' }) >]'
. There might be a shorter "formula", but this seems good enough. \$\endgroup\$Danko Durbić– Danko Durbić2015年12月11日 15:51:49 +00:00Commented Dec 11, 2015 at 15:51 -
\$\begingroup\$ @DankoDurbić Excellent! I was trying to come up with some math to select on the correct output character based on ASCII values, but I couldn't find the right formula. I kept getting tripped up by
()
being right next to each other, but the other brackets have a character between, so I went with indexing. Thanks! \$\endgroup\$AdmBorkBork– AdmBorkBork2015年12月11日 16:02:52 +00:00Commented Dec 11, 2015 at 16:02 -
\$\begingroup\$ Using
String.Replace()
instead of the-replace
operator would buy you another 2 bytes (no need to escape or define a character class with[]
) \$\endgroup\$Mathias R. Jessen– Mathias R. Jessen2015年12月12日 23:28:32 +00:00Commented Dec 12, 2015 at 23:28 -
\$\begingroup\$ @MathiasR.Jessen Unless I'm missing something here, the
.Replace('[]{}()<>;,',' ')
won't catch individual characters but instead try to match the symbolic whole, which doesn't exist. We'd need to use Regex.Replace, which involves a[regex]::
.NET call and would instead lengthen the code. \$\endgroup\$AdmBorkBork– AdmBorkBork2015年12月14日 14:20:49 +00:00Commented Dec 14, 2015 at 14:20 -
\$\begingroup\$ @TessellatingHeckler Thanks! I golfed another byte using
-ne''
instead of|?{$_}
. \$\endgroup\$AdmBorkBork– AdmBorkBork2015年12月15日 14:48:08 +00:00Commented Dec 15, 2015 at 14:48
Python 2, 96 bytes
import re
lambda(a,(b,c)):(b+c.join(re.findall('[-\d\.]+',a))+'])>} '['[(<{ '.index(b)]).strip()
Call as:
f(('{-1.3, 3.4, ,4, 5.55555555}','[,'))
Output:
[-1.3,3.4,4,5.55555555]
JavaScript (ES6), (削除) 82 (削除ここまで) (削除) 92 (削除ここまで) (削除) 116 (削除ここまで) 92 bytes
(a,b)=>(c=a.match(/-?\d+(\.\d+)?/g).join(b[1]),d=b[0],d<"'"?c:d+c+"]}>)"["[{<(".indexOf(d)])
An anonymous function, run it like this
((a,b)=>(c=a.match(/-?\d+(\.\d+)?/g).join(b[1]),d=b[0],d<"'"?c:d+c+"]}>)"["[{<(".indexOf(d)]))("{1; 2;3; 4}","<;")
This can probably be golfed way further..
Ungolfed
(a,b)=>( // "{1; 2;3; 4}", "<;"
c=a.match(/-?\d+(\.\d+)?/g) // regex to match decimals
.join(b[1]), // c -> "1;2;3;4"
d=b[0], // d -> "<"
d<"'" ? // if d is smaller than ' then ...
c : // return just "1;2;3;4"
d + c + // "<" + "1;2;3;4" + ...
"]}>)" [ "[{<(".indexOf(d) ] // "]}>)"[2] -> ">"
)
-
\$\begingroup\$ I think you have to take a as a string, not a list. \$\endgroup\$overactor– overactor2015年12月11日 09:23:12 +00:00Commented Dec 11, 2015 at 9:23
-
\$\begingroup\$ Totally misunderstood this:
The input will be a list of integer or decimal numbers (both positive and negative (and zero)), and a string of two characters
. Fixed it, thanks \$\endgroup\$Bassdrop Cumberwubwubwub– Bassdrop Cumberwubwubwub2015年12月11日 09:48:33 +00:00Commented Dec 11, 2015 at 9:48
Mathematica, 108 bytes
Mathematica is generally clumsy with string inputs unless the string is meant to be interpreted as a text.
c=Characters;t_~f~p_:=({b,s}=c@p;b<>Riffle[StringCases[t,NumberString],s]<>(b/.Thread[c@"[ {<(" -> c@"] }>)"]))
Explanation
StringCases[t,NumberString]
returns the list of number strings.
Riffle
inserts the separators between the numbers.
/.Thread[c@"[ {<(" -> c@"] }>)"])
replaces the left "bracket" with the right bracket.
<>
is the infix form of StringJoin
. It glues together the substrings.
Bash + GNU Utilities, 90
b=${2:0:1}
echo $b`sed "s/[][{}()<>]//g;s/[,; ]\+/${2:1}/g"<<<"1ドル"``tr '[{(<' ']})>'<<<$b`
Matlab, 85 bytes
@(s,x)[x(1) strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)) x(1)+(x(1)~=32)+(x(1)~=40)]
Example use:
>> @(s,x)[x(1) strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)) x(1)+(x(1)~=32)+(x(1)~=40)]
ans =
@(s,x)[x(1),strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)),x(1)+(x(1)~=32)+(x(1)~=40)]
>> ans('1 2.4 -3 -444.555 5', '[,')
ans =
[1,2.4,-3,-444.555,5]
CJam, 27 bytes
l)l_5ms`-SerS%*\S-_o_'(#(f-
Explanation
l e# Read the format string.
) e# Extract the separator.
l_ e# Read the list.
5ms` e# Get a string that contains -.0123456789.
- e# Get the characters in the list that are not in the string.
Ser e# Replace those characters with spaces.
S% e# Split by those characters, with duplicates removed.
* e# Join with the separator.
\S- e# Remove spaces (if any) from the left bracket.
_o e# Output a copy of that character before the stack.
_'(# e# Find '( in the left bracket string.
( e# Get -1 if '( is the first character, and -2 if it doesn't exist.
f- e# Subtract the number from every character in the left bracket string,
making a right bracket.
Julia, 95 bytes
f(l,s)=(x=s[1]<33?"":s[1:1])*join(matchall(r"[\d.-]+",l),s[2])*string(x>""?s[1]+(s[1]<41?1:2):x)
This is a function f
that accepts two strings and returns a string.
Ungolfed:
function f{T<:AbstractString}(l::T, s::T)
# Extract the numbers from the input list
n = matchall(r"[\d.-]+", l)
# Join them back into a string separated by given separator
j = join(n, s[2])
# Set the opening bracket type as the empty string unless
# the given bracket type is not a space
x = s[1] < 33 ? "" : s[1:1]
# Get the closing bracket type by adding 1 or 2 to the ASCII
# value of the opening bracket unless it's an empty string
c = string(x > "" ? s[1] + (s[1] < 41 ? 1 : 2) : x)
# Put it all together and return
return x * j * c
end
_
to denote negative elements. :( \$\endgroup\$