12
2
I define the following operators:
Manhattan Addition a +M b, for single-digit numbers, is the result of concatenating b onto a. So, a +M b = 10a + b. Therefore, the general operator +M is defined as thus:
a +M b = 10a + b
Manhattan Subtraction a –M b, for single-digit numbers, is the result of removing the last b from a. Therefore, the operator –M is defined as thus in pseudocode:
a –M b = a remove last b
Manhattan Multiplication a ×M b is the result of replacing all instances of b in a with b instances of b. Ergo, ×M is defined in pseudocode as:
a ×M b = a -> s/b/<b copies of b>/g
Manhattan Division a ÷M b is defined in terms of ×M:
1 ÷M b = the first character of b a ÷M b = a ×M (1 ÷M b)
With all this in mind, create an interpreter that will evaluate infix expressions that use the following operators (i.e., a + b
, not a b +
or + a b
)
+ Addition
- Subtraction
/ Division
* Multiplication
*M Manhattan Multiplication
/M Manhattan Division
+M Manhattan Addition
-M Manhattan Subtraction
Each Manhattan operator has a higher order precedence than their normal counterpart.
Test cases:
> 5 +M 10 + 3
63 // 5*10 + 10 + 3 => 60 + 3
> 10 *M 2
10 // no 2s in 10
> 10 *M 1
10 // one 1 in 10 replaced once
> 23 *M 3
2333 // 23 has one 3, which is replaced with three 3s
> 23 *M 2
223 // 23 has one 2, which is replaced with two 2s
> 232 *M 2
22322 // 232 has two 2s, which are replaced with two 2s
> 232 *M 23
23...(23 times)...232 // ...
> 123 *M 2 * 3
3669 // 1223 * 3 => 3669
> 5 + 3 +M 2
37 // 5 + (3 +M 2) => 5 + 32 => 37
> 150 /M 3
150 // 150 ÷M 3 => 150 ×M 3 => 150
> 150 /M 53
1555550 // 150 ÷M 53 => 150 ×M 5 => 1555550
> 50 -M 0
5
> 500 -M 0
50
> 5234 -M 5
234
> 12 +M 633 *M 3
6333453 // = 12 +M 6333333 = 120 + 6333333 = 6333453
This is a code-golf, so the shortest program in bytes wins.
Leaderboards
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
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 leaderboard snippet:
# [><>](http://esolangs.org/wiki/Fish), 121 bytes
var QUESTION_ID=59299,OVERRIDE_USER=8478;function answersUrl(e){return"http://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"http://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>
13Why are you using the Unicode symbols
×
and÷
instead of ASCII*
and/
? – ASCIIThenANSI – 2015-10-01T19:47:10.9401Why does
232 ×M 23
equal23232
? Shouldn't it equal 23 copies of23
followed by a2
? – senshin – 2015-10-01T21:25:49.207@senshin Sorry, yes. right. – Conor O'Brien – 2015-10-01T21:33:01.303
1@ASCIIThenANSI I can see why you asked that. The choice is arbitrary. Unless if there is some pressing issue with my choice, I don't think I'll change it. – Conor O'Brien – 2015-10-01T21:33:34.187
4It makes it arbitrarily harder for languages without good Unicode support to participate, which is not very fun, if the challenge isn't about Unicode. – Lynn – 2015-10-01T21:48:04.403
@Mauris Ah. kay then. – Conor O'Brien – 2015-10-01T21:49:23.203
So $a -M b = a$ if $a ≠ b$, $0$ otherwise? Or are $a +M b$ and $a -M b$ defined for arbitrary $a$ and single-digit $b$? Also, should we suppose base 10? – Édouard – 2015-10-08T04:23:59.337
Your definition of subtraction is not related to single digit numbers. Maybe
b
is single digit but nota
– edc65 – 2015-10-08T06:07:59.5802This question has not received enough attention because is not well specified. You define addition for sngle digit numbers, then your first example have 2 digits numbers. I give up... – edc65 – 2015-10-08T06:25:29.947
@edc65 I clearly defined (fine, specified) what each operator should do. Feel free to give up. – Conor O'Brien – 2015-10-08T11:00:24.197
Do
*
and/
have higher precedence than+
and-
? What about*M
and/M
vs+M
and-M
? – lirtosiast – 2015-10-08T12:54:30.550How much flexibility do we need in our handling of whitespace? – lirtosiast – 2015-10-08T12:55:46.643
@ThomasKwa I didn't specify it, so whatever works best for your program is fine by me. – Conor O'Brien – 2015-10-08T13:02:30.210
1@edc65 He clearly states
a +M b = 10a + b
. This is in general, not just for single-digit numbers. The concatenation method was the one that was only for single digit numbers. – mbomb007 – 2015-10-08T13:56:56.2431Can we assume that
-M
will always be called with ana
that contains at least oneb
? – lirtosiast – 2015-10-08T14:09:44.287@ThomasKwa Yes. – Conor O'Brien – 2015-10-08T14:42:06.910
You need some better test cases that test operator precedence, and also a test more than one or two operations at once. – mbomb007 – 2015-10-08T15:24:19.937
@mbomb007 I should, and will do so when the time becomes available. – Conor O'Brien – 2015-10-08T15:27:24.963
Which comes first in order of operations?
*M
or/M
? Same question with+M
and-M
. They aren't inverses of each other, so I think they need to have a fixed order. Or is it just going to be left-to-right? – mbomb007 – 2015-10-08T15:57:41.033The same as normal: As
*
and/
are evaluated first, from left-to-right, so are*M
and/M
. – Conor O'Brien – 2015-10-08T17:05:09.557@CᴏɴᴏʀO'Bʀɪᴇɴ You’ve left several questions about your specs unanswered. First of all, your operations are not defined on numbers, but on their representations. I suppose that you want us to use base 10 representations at all time, but it’s not in the specs. If I get it right, 2 -M 1 = 2 if we suppose base 10, but 1 if we suppose base 2. – Édouard – 2015-10-09T16:10:39.017
@CᴏɴᴏʀO'Bʀɪᴇɴ Second, you define +M and -M for single digits, then you say “in general”. Does that mean “for any integer”? Because, then, I’m not sure whether 123 -M 12 = 3 and I have no idea what 123 -M 13 is. – Édouard – 2015-10-09T16:16:56.677
@Édouard Yes, in general applies to all integers.
123 -M 12 = 3
and123 -M 13 = 123
. If there is no instance ofb
ina
, thena
remains unchanged. – Conor O'Brien – 2015-10-09T16:18:50.570You should add
4342343 -M 34
→43423
as a test case. – Adám – 2016-06-30T06:53:46.363