User Scored Code Golf - Drawing Diamonds [experimental]

11

2

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.

  • You may edit your answer as much as you want.

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)|[ -~]) ####$/
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
}

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)   
}

function addAnalytics() {
    //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)
    
    //invalid answers
    var invalida = ''
    if (invalidAnswers.length > 0) {
        for (var i = 0; i < invalidAnswers.length; i++) {
            var a = invalidAnswers[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

Calvin's Hobbies

Posted 2015-01-27T11:35:30.930

Reputation: 84 000

>1 -> *< – Martin Ender – 2015-01-27T12:11:24.980

Comments can be edited for 5 minutes, so allowing them to be edited could cause complete havok with the non-repetition rules. – Peter Taylor – 2015-01-27T12:15:56.143

@PeterTaylor But how can I possibly stop comment edits? Besides totally ignoring ones that are edited. 5 minutes goes pretty fast. – Calvin's Hobbies – 2015-01-27T12:17:06.497

1I 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. – Peter Taylor – 2015-01-27T12:23:15.120

>2 -> :< – Logic Knight – 2015-01-27T12:57:13.087

>3 -> 3< – kennytm – 2015-01-27T13:44:10.970

>5 -> \s< – agweber – 2015-01-27T15:33:32.967

>6 -> (< – Kristoffer Sall-Storgaard – 2015-01-27T15:55:15.580

>7 -> @< – randomra – 2015-01-27T16:22:36.410

>8 -> [< – Zgarb – 2015-01-27T16:28:58.040

>9 -> =< – Alex A. – 2015-01-27T16:42:28.717

>93 -> +< – jimmy23013 – 2015-01-27T17:38:22.393

>94 -> )< – Jørgen R – 2015-01-27T19:31:44.970

>25 -> b< – Jakube – 2015-01-27T20:40:27.887

>95 -> '< – Frxstrem – 2015-01-28T01:39:52.080

stressed desserts – unclemeat – 2015-01-28T03:21:22.080

>4 -> I< – justhalf – 2015-01-28T04:06:46.420

>10 -> $< – Stephen – 2015-01-28T11:18:41.517

Answers

4

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~

jimmy23013

Posted 2015-01-27T11:35:30.930

Reputation: 34 042

5

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.

Logic Knight

Posted 2015-01-27T11:35:30.930

Reputation: 6 622

3

Pyth, 21 bytes

L+_tbbjbymy+>zd*\ dlz

Try it online: Pyth Compiler/Executor

Jakube

Posted 2015-01-27T11:35:30.930

Reputation: 21 462

2

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.

Martin Ender

Posted 2015-01-27T11:35:30.930

Reputation: 184 808

1

J, 45 chars

(({~((]*]<#@[)>:@(+/~)@:|@i:@(2-#)))@(' '&,))

Longish solution, will golf it with some cheap chars...

Try it online. (Append input string with single quotes.)

randomra

Posted 2015-01-27T11:35:30.930

Reputation: 19 909

1

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.

Stephen

Posted 2015-01-27T11:35:30.930

Reputation: 201

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. – Ismael Miguel – 2015-01-28T17:16:05.580

0

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);}}

Ypnypn

Posted 2015-01-27T11:35:30.930

Reputation: 10 485