Está diseñando un nuevo lenguaje de programación esotérico y una característica que ha decidido agregar es un asignador dinámico de memoria. Su idioma especifica un espacio de dirección virtual dedicado especial para el espacio del programa del usuario. Esto es independiente del espacio de direcciones utilizado por el asignador de memoria para cualquier estado interno.
Para ayudar a reducir el costo de distribuir su implementación, el tamaño del código debe ser lo más pequeño posible.
Interfaz
Debe proporcionar tres funciones: inicialización, asignación y desasignación.
Inicialización
Esta función toma un único parámetro entero positivo N
. Esto significa que el programa de un usuario tiene N
bytes en su espacio de direcciones desde los cuales hay N-1
bytes para asignar memoria. La dirección 0
está reservada para "nulo".
Se garantiza que esta función se invocará exactamente una vez antes de cualquier llamada de asignación / desasignación.
Tenga en cuenta que esta función no necesita asignar ninguna memoria física para el espacio de direcciones virtuales del programa de usuario; básicamente está creando la "apariencia" de un asignador de memoria hueca.
Asignar
La función de asignación debe tomar una solicitud del número de bytes de memoria para asignar. La entrada está garantizada para ser positiva.
Su función debe devolver una dirección entera al comienzo del bloque asignado, o 0
para indicar que no hay un bloque contiguo del tamaño solicitado disponible. ¡Si un bloque contiguo del tamaño disponible está disponible en cualquier parte del espacio de direcciones, debe asignarlo!
Debe asegurarse de que no se superpongan dos bloques asignados.
Desasignar
La función de desasignación debe tomar una dirección del inicio de un bloque asignado y, opcionalmente, también puede tomar el tamaño del bloque dado.
La memoria que se ha desasignado está disponible nuevamente para asignación. Se supone que la dirección de entrada es una dirección válida.
Ejemplo de implementación de Python
Tenga en cuenta que puede elegir cualquier método para realizar un seguimiento del estado interno; en este ejemplo, la instancia de clase lo rastrea.
class myallocator:
def __init__(self, N):
# address 0 is special, it's always reserved for null
# address N is technically outside the address space, so use that as a
# marker
self.addrs = [0, N]
self.sizes = [1, 0]
def allocate(self, size):
for i,a1,s1,a2 in zip(range(len(self.addrs)),
self.addrs[:-1], self.sizes[:-1],
self.addrs[1:]):
if(a2 - (a1+s1) >= size):
# enough available space, take it
self.addrs.insert(i+1, a1+s1)
self.sizes.insert(i+1, size)
return a1+s1
# no contiguous spaces large enough to take our block
return 0
def deallocate(self, addr, size=0):
# your implementation has the option of taking in a size parameter
# in this implementation it's not used
i = self.addrs.index(addr)
del self.addrs[i]
del self.sizes[i]
Puntuación
Este es el código de golf; el código más corto en bytes gana. No necesita preocuparse por quedarse sin memoria para cualquier estado interno requerido por su asignador.
Se aplican agujeros de bucle estándar.
Tabla de clasificación
var QUESTION_ID=67895,OVERRIDE_USER=31729;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>
To help reduce the cost of distributing your implementation the size of the code must be as small as possible
o podría ser eficiente (pequeño y eficiente no son lo mismo) como sea posible? : DRespuestas:
Rubí, 80
Como la respuesta de MegaTom, pero usa una cadena en lugar de una matriz para almacenar el estado. El carácter "o" denota una celda abierta, mientras que una "f" denota una llena. Esto nos permite usar las funciones de manipulación de cadenas relativamente concisas de Ruby:
?o*n
inicializa una cadena de n "o" s./\B#{?o*n}/
es una expresión regular que coincide con n "o" consecutivas que no incluye el primer carácter.sub!
reemplaza el primer partido con n "f" s."#$`"
da la cadena a la izquierda de la coincidencia, o una cadena vacía si no hubo coincidencia, por lo que el tamaño es el índice asignado o 0.Deallocate solo establece la sección designada de la cadena de nuevo a "o" s.
fuente
JavaScript (ES6), 88
Usar una variable global
_
(una matriz muy escasa) para realizar un seguimiento.Ahora, ¿cómo podría probarlo?
fuente
Ruby, 135
Tiene una matriz global que realiza un seguimiento de si cada celda está asignada o no.
fuente
Mathematica, 152
n
almacenar el tamaño total,l
almacena el estado interno. El asignador intentará asignar justo detrás de otra sección de memoria asignada.fuente