# User Scored Code Golf - Drawing Diamonds [experimental]

This challenge will behave more or less like a traditional . The only difference is that instead of scoring answers by their number of characters or bytes, users will assign weights to different characters in the comments and the program with the lowest cumulative weight will win.

# Challenge

Your task is to write a program that takes a string and prints a diamond shape where the first character starts in the center and subsequent characters occupy the empty spaces orthogonal to the set of characters that were placed last. Spaces ( ) will be used for padding.

For example inputting CAT would produce

  T
TAT
TACAT
TAT
T


and () would produce

 )
)()
)


and  desserts would produce

        s
sts
strts
strerts
streserts
stressserts
stressesserts
stressedesserts
stressed desserts
stressedesserts
stressesserts
stressserts
streserts
strerts
strts
sts
s


and 9 would produce 9.

# Details

• The code may only contain printable ASCII and newlines. (See why below.)

• Input/output should be via stdin/stdout, or, if they aren't possible, use similar alternatives.

• You may assume the input string only contains printable ASCII (including space).

• Columns of leading spaces not containing any portion of the diamond pattern are not allowed in the output. Any amount and combination of trailing spaces spaces is allowed.

• There may optionally be a trailing newline in the output.

# Scoring

All code must be written using only newlines and the 95 printable ASCII characters:

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~ (Sadly tabs are not allowed because Stack Exchange renders them as spaces in code blocks.) Each of these 96 characters has a weight value associated with it. By default, all the weights are 97. The score of a program is the sum of the weight values for each of its characters. For example, if the program were print(4) and the weight for 4 was 70, but unchanged for everything else, the score would be 749 = 97+97+97+97+97+97+70+97. Once the activity in this question settles down to almost nothing, the lowest scoring submission wins. In the presumably unlikely case of tie the wins goes to the highest voted answer. # Changing Weights Every user, whether they've answered or not, can change the weight of one of the 96 characters to a unique value from 1 to 96. To do this, add a comment to this question of the form #### W -> C ####, where W is an integer from 1 to 96 and C is the character (as itself, no quotes, no backticks). Use \n in place of C for newlines and \s for space since Stack Exchange compresses 3 spaces in a row. The print(4) example above would have had the comment #### 70 -> 4 ####. Each user may only make ONE comment like this, and it will only be valid if both the character and the weight value have not been used in a previously made comment. Thus eventually, there may be 96 #### W -> C #### comments, all from different users, all with different weights assigned to different characters. Users may delete their own comment if they want to, resetting their characters' weight back to 97 until they or someone else comments again. They may also edit them. Comments not following the rules about distinct users/weights/characters should be deleted or flagged as "not constructive". General comments about rules and other things are fine but should be kept at a minimum. This stack snippet is the official leaderboard for this question. It automatically computes the scores for all submissions by gathering the weights from comments each time it is run. It does not handle ties. You can also use it to check the score a program would have. You'll probably need to right-click -> Open link in new tab for the links. function compute(){var e=computeScore($("#code").val());$("#score").val(e==-1?"Invalid characters":e)}function computeScore(e){var t=0;for(var n=0;n<e.length;n++){if(weights.hasOwnProperty(e[n])){t+=weights[e[n]]}else{return-1}}return t}function htmlDecode(e){var t=document.createElement("div");t.innerHTML=e;return t.childNodes.length===0?"":t.childNodes[0].nodeValue}function addLeaderboard(){validAnswers.sort(function(e,t){return e.score>t.score});var e=1;var t="";for(var n=0;n<validAnswers.length;n++){var r=validAnswers[n];t+="<tr><td>"+e+"</td><td><a href='"+r.link+"'>"+r.owner.display_name+"</a></td><td>"+r.score+"</td><td>"+r.length+"</td></tr>";if(n+1<validAnswers.length&&validAnswers[n+1].score>r.score){e++}}$("#leaderboard").append(t)}function addAnalytics(){var e="";for(var t in weights){if(weights.hasOwnProperty(t)&&weights[t]!=defaultWeight){e+=(t=="\n"?"\\n":t)+"="+weights[t]+" "}}$("#weights").val(e);var n="";for(var t in usedChars){if(usedChars.hasOwnProperty(t)&&usedChars[t]==false){n+=t=="\n"?"\\n":t}}$("#unusedc").val(n);var r="";for(var t in usedWeights){if(usedWeights.hasOwnProperty(t)&&usedWeights[t]==false){r+=t+" "}}$("#unusedw").val(r);var i="";if(invalidComments.length>0){for(var s=0;s<invalidComments.length;s++){var o=invalidComments[s];i+="<a href='#"+o.link+"'>"+o.owner.display_name+"</a> "}}else{i="none"}$("#comments").html(i);var u="";if(invalidAnswers.length>0){for(var s=0;s<invalidAnswers.length;s++){var a=invalidAnswers[s];u+="<a href='#"+a.link+"'>"+a.owner.display_name+"</a> "}}else{u="none"}$("#answers").html(u)}function checkAnswers(e){for(var t=0;t<e.items.length;t++){var n=e.items[t];var r=answerPattern.exec(n.body);if(r){var i=htmlDecode(r[1]);var s=computeScore(i);if(s==-1){invalidAnswers.push(n)}else{n.length=i.length;n.score=s;validAnswers.push(n)}}else{invalidAnswers.push(n)}}addLeaderboard();addAnalytics()}function checkComments(e){for(var t=0;t<e.items.length;t++){var n=e.items[t];var r=commentPattern.exec(htmlDecode(n.body));if(r){var i=n.owner.user_id;var s=parseInt(r[1]);var o=r[2]=="\\n"?"\n":r[2]=="\\s"?" ":r[2];if(userIDs.hasOwnProperty(i)||!usedWeights.hasOwnProperty(s)||usedWeights[s]||!usedChars.hasOwnProperty(o)||usedChars[o]){invalidComments.push(n)}else{userIDs[i]=true;usedWeights[s]=true;usedChars[o]=true;weights[o]=s}}}$.get(answersURL,checkAnswers)}function refresh(){$.get(commentsURL,checkComments)}questionID=45040;commentsURL="https://api.stackexchange.com/2.2/questions/"+questionID+"/comments?order=asc&sort=creation&site=codegolf&filter=!t)IWLXOkOvAuPe8m2xJrXOknWcw(ZqZ";answersURL="https://api.stackexchange.com/2.2/questions/"+questionID+"/answers?order=desc&sort=activity&site=codegolf&filter=!.FjsvG2LuND(frE*)WTvqQev1.lyu";commentPattern=/^#### (\d+) -> (\\(?:n|s)|[ -~]) ####$/;answerPattern=/<pre><code>((?:\n|.)*?)\n<\/code><\/pre>/;chars="\n !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~";validAnswers=[];invalidAnswers=[];invalidComments=[];userIDs={};usedWeights={};usedChars={};weights={};defaultWeight=chars.length+1;for(var i=0;i<chars.length;i++){usedChars[chars[i]]=false;usedWeights[i+1]=false;weights[chars[i]]=defaultWeight}refresh() *{font-family:Helvetica,Arial,sans-serif}table{border:3px solid green;border-collapse:collapse}button{font-size:100%}th{background-color:green;color:#fff;padding:6pt}td{border:1px solid green;padding:6pt}.large{font-size:140%}.title{font-weight:700;margin:6pt 0}textarea{font-family:"Courier New";white-space:nowrap;overflow:auto}input[readonly]{background-color:#dcdcdc}.analytics{font-size:90%;padding:4pt 0 0} <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class='large title'>Leaderboard</div><table id='leaderboard'> <tr> <th>Place</th> <th>Submitter</th> <th>Score</th> <th>Program Length</th> </tr></table><br><div class='title'>Compute Score</div><textarea id='code' rows='5' cols='40' placeholder='paste code here...'></textarea><br><button type='button' onclick='compute()'>Compute</button> Score: <input type='text' id='score' readonly><br><br><div class='title'>Analytics</div><div class='analytics'>Assigned weights: <input type='text' id='weights' readonly></div><div class='analytics'>Unused characters: <input type='text' id='unusedc' readonly> (all weight 97)</div><div class='analytics'>Unused weights: <input type='text' id='unusedw' readonly></div><div class='analytics'>Invalid comments (duplicate user/char/weight):&nbsp;<span id='comments'></span></div><div class='analytics'>Invalid answers (illegal characters or no code block):&nbsp;<span id='answers'><span></div><br><button type='button' onclick='refresh'>Refresh</button> For this leaderboard to work, the comments must be in the exact format described above and your program's code must be in the first multi-line code block in your answer (the <pre><code>...</code></pre> ones). Don't use syntax highlighting or your code won't be read correctly. The snippet can take a minute or two before it updates. I have not tested the snippet thoroughly but I'll be keeping an eye on it as this contest gets underway. If you notice any bugs please tell me. Here is an non-minified version: questionID = 45040 commentsURL = 'https://api.stackexchange.com/2.2/questions/' + questionID + '/comments?order=asc&sort=creation&site=codegolf&filter=!t)IWLXOkOvAuPe8m2xJrXOknWcw(ZqZ' answersURL = 'https://api.stackexchange.com/2.2/questions/' + questionID + '/answers?order=desc&sort=activity&site=codegolf&filter=!.FjsvG2LuND(frE*)WTvqQev1.lyu' commentPattern = /^#### (\d+) -> (\\(?:n|s)|[ -~]) ####$/

chars = '\n !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~' validAnswers = [] invalidAnswers = [] invalidComments = [] userIDs = {} usedWeights = {} usedChars = {} weights = {} defaultWeight = chars.length + 1 for (var i = 0; i < chars.length; i++) { usedChars[chars[i]] = false usedWeights[i + 1] = false weights[chars[i]] = defaultWeight } function compute() { var score = computeScore($('#code').val())
$('#score').val(score == -1 ? 'Invalid characters' : score) } function computeScore(code) { var score = 0 for(var i = 0; i < code.length; i++) { if (weights.hasOwnProperty(code[i])) { score += weights[code[i]] } else { return -1 } } return score } function htmlDecode(input) { var e = document.createElement('div') e.innerHTML = input; return e.childNodes.length === 0 ? '' : e.childNodes[0].nodeValue } function addLeaderboard() { validAnswers.sort(function(a,b) { return a.score > b.score} ) var place = 1 var rows = '' for(var i = 0; i < validAnswers.length; i++) { var a = validAnswers[i] rows += '<tr><td>' + place + "</td><td><a href='" + a.link + "'>" + a.owner.display_name + "</a></td><td>" + a.score + '</td><td>' + a.length + '</td></tr>' if (i + 1 < validAnswers.length && validAnswers[i + 1].score > a.score) { place++ } }$('#leaderboard').append(rows)
}

//assigned weights
var assigned = ''
for (var key in weights) {
if (weights.hasOwnProperty(key) && weights[key] != defaultWeight) {
assigned += (key == '\n' ? '\\n' : key) + '=' + weights[key] + ' '
}
}
$('#weights').val(assigned) //unused chars var unusedc = '' for (var key in usedChars) { if (usedChars.hasOwnProperty(key) && usedChars[key] == false) { unusedc += key == '\n' ? '\\n' : key } }$('#unusedc').val(unusedc)

//unused weights
var unusedw = ''
for (var key in usedWeights) {
if (usedWeights.hasOwnProperty(key) && usedWeights[key] == false) {
unusedw += key + ' '
}
}
$('#unusedw').val(unusedw) //invalid comments var invalidc = '' if (invalidComments.length > 0) { for (var i = 0; i < invalidComments.length; i++) { var c = invalidComments[i] invalidc += "<a href='#" + c.link + "'>" + c.owner.display_name + '</a> ' } } else { invalidc = 'none' }$('#comments').html(invalidc)

var invalida = ''
for (var i = 0; i < invalidAnswers.length; i++) {
invalida += "<a href='#" + a.link + "'>" + a.owner.display_name + '</a> '
}
} else {
invalida = 'none'
}
$('#answers').html(invalida) } function checkAnswers(answers) { for (var i = 0; i < answers.items.length; i++) { var answer = answers.items[i] var match = answerPattern.exec(answer.body) if (match) { var code = htmlDecode(match[1]) var score = computeScore(code) if (score == -1) { invalidAnswers.push(answer) } else { answer.length = code.length answer.score = score validAnswers.push(answer) } } else { invalidAnswers.push(answer) } } addLeaderboard() addAnalytics() } function checkComments(comments) { for (var i = 0; i < comments.items.length; i++) { var comment = comments.items[i] var match = commentPattern.exec(htmlDecode(comment.body)) if (match) { var userID = comment.owner.user_id var weight = parseInt(match[1]) var char = match[2] == '\\n' ? '\n' : (match[2] == '\\s' ? ' ' : match[2]) //check validity if (userIDs.hasOwnProperty(userID) || !usedWeights.hasOwnProperty(weight) || usedWeights[weight] || !usedChars.hasOwnProperty(char) || usedChars[char]) { invalidComments.push(comment) } else { userIDs[userID] = true usedWeights[weight] = true usedChars[char] = true weights[char] = weight } } }$.get(answersURL, checkAnswers)
}

function refresh() {
$.get(commentsURL, checkComments) } refresh() * { font-family: Helvetica, Arial, sans-serif; } table { border: 3px solid green; border-collapse: collapse; } button { font-size: 100%; } th { background-color: green; color: white; padding: 6pt; } td { border: 1px solid green; padding: 6pt; } .large{ font-size: 140%; } .title{ font-weight: bold; margin: 6pt 0 6pt 0; } textarea { font-family: "Courier New"; white-space: nowrap; overflow: auto; } input[readonly] { background-color: gainsboro; } .analytics { font-size: 90%; padding: 4pt 0 0 0; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class='large title'>Leaderboard</div> <table id='leaderboard'> <tr> <th>Place</th> <th>Submitter</th> <th>Score</th> <th>Program Length</th> </tr> </table> <br> <div class='title'>Compute Score</div> <textarea id='code' rows='5' cols ='40' placeholder='paste code here...'></textarea><br> <button type='button' onclick='compute()'>Compute</button> Score: <input type='text' id='score' readonly> <br> <br> <div class='title'>Analytics</div> <div class='analytics'>Assigned weights: <input type='text' id='weights' readonly></div> <div class='analytics'>Unused characters: <input type='text' id='unusedc' readonly> (all weight 97)</div> <div class='analytics'>Unused weights: <input type='text' id='unusedw' readonly></div> <div class='analytics'>Invalid comments (duplicate user/char/weight):&nbsp;<span id='comments'></span></div> <div class='analytics'>Invalid answers (illegal characters or no code block):&nbsp;<span id='answers'><span></div> <br> <button type='button' onclick='refresh'>Refresh</button> Keep in mind that this scoring system is completely new and experimental. Hopefully Stack Exchange won't mind that it involves tons of comments. :P Related challenge: Print this diamond • #### 1 -> * #### Jan 27 '15 at 12:11 • Comments can be edited for 5 minutes, so allowing them to be edited could cause complete havok with the non-repetition rules. Jan 27 '15 at 12:15 • @PeterTaylor But how can I possibly stop comment edits? Besides totally ignoring ones that are edited. 5 minutes goes pretty fast. Jan 27 '15 at 12:17 • I don't like this scoring system at all (see chat), but if you're going to use it then ignoring comments which are edited is definitely the right thing to do. Jan 27 '15 at 12:23 • #### 2 -> : #### Jan 27 '15 at 12:57 ## 8 Answers # Python 2, 120 bytes T=raw_input() L=len(T) r=[b[::-1]+b[1:]for b in [T[-b:]+' '*(L-b)for b in range(1,L+1)]] for b in r[:-1]+r[::-1]:print b  Edit: Lowered cost with some cheaper characters. # CJam, 144 150 bytes "x*3:*3:3*::33:3:::333*::333*3::***3::**::33:3::3*:::::*3:3:3:**33*333333::33*:*333:*3*3**:**3:**:3*3:33*3:3*:333**:3**33:*3:::*:3*::3"'3/'b*3b127b:c~  Tried some encoding... Updated because the weight of b has changed. Another encoding which is only better in theory (140 bytes): ":***(*3:**3*I**:3*****:*3*******: ::::*:***II@3*******: :**I:**:***:*3***3*I3I:3***33:::*I**3I***3***:3:*I*3I"{"*:I3( **@"#1a*~0}%2b126b:c~  # Pyth, 21 bytes L+_tbbjbymy+>zd*\ dlz  Try it online: Pyth Compiler/Executor # CJam, 31 bytes lW%_,:I(S*\+I*I/2%{_W%1>+z}2*N*  Just an adaptation of my answer to Print this diamond for now. I might tweak it when the weights have changed. Test it here. # J, 45 chars (({~((]*]<#@[)>:@(+/~)@:|@i:@(2-#)))@(' '&,))  Longish solution, will golf it with some cheap chars... Try it online. (Append input string with single quotes.) # PHP (131 chars) function f($s){for($i=-($l=strlen($s));$i<$l;$I=abs(++$i)){$t=substr($s,$I);echo str_repeat(' ',$I).strrev($t).substr($t,1)."\n";}}  http://3v4l.org/9Vvkm Will optimise once the weightings are clearer. • Your code may be rewritten into this: function f($s){for($i=-($l=strlen($s));$i<$l;)echo str_repeat(' ',$I=abs(++$i)),strrev($t=substr($s,$I)),substr($t,1),"\n";} which might not work. But it is 6 bytes shorter! Probably you might take something from here. Jan 28 '15 at 17:16 # Vyxalj, 61 bytes, score 4890. fK\a:-$vj:vL?Lv-\ v*$+?:L1-wifK\a:-$vjvm2v/vt\a:-p+:wRh1?L"iJ


Try it Online!

This was painful, especially in a language with a huge codepage that I can only use a small bit of.

Score calculation + explanation coming soon.

Thanks to lyxal for finding some clever ways for me to do various things.

## Java, 318 bytes

class N{public static void main(String[]a){char[]s=new java.util.Scanner(System.in).nextLine().toCharArray();int l=s.length,m=l-1,$=0,b;String t="";for(;$<l;$++,t+='\n')for(b=0;b<l+$;b++)t+=b+$<m?' ':s[b>m?m-b+$:b+$-m];for($=l-2;$>-1;$--,t+='\n')for(b=0;b<l+$;b++)t+=b+$<m?' ':s[b>m?m-b+$:b+$-m];System.out.print(t);}}
`