Вы разрабатываете новый эзотерический язык программирования, и одну из функций, которую вы решили добавить, это динамический распределитель памяти. Ваш язык определяет специальное выделенное виртуальное адресное пространство для программного пространства пользователя. Это отдельно от адресного пространства, используемого распределителем памяти для любого внутреннего состояния.
Чтобы снизить стоимость распространения вашей реализации, размер кода должен быть как можно меньше.
Интерфейс
Вы должны предоставить три функции: инициализация, распределение и освобождение.
инициализация
Эта функция принимает один положительный целочисленный параметр N
. Это означает, что у программы пользователя есть N
байты в его адресном пространстве, из которого есть N-1
байты для выделения памяти. Адрес 0
зарезервирован для «ноль».
Гарантируется, что эта функция будет вызываться ровно один раз перед любыми вызовами выделения / удаления.
Обратите внимание, что этой функции не нужно выделять физическую память для виртуального адресного пространства программы пользователя; вы в основном создаете «внешний вид» полого распределителя памяти.
ассигновать
Функция allocate должна принять запрос количества байтов памяти для выделения. Вход гарантированно будет положительным.
Ваша функция должна возвратить целочисленный адрес в начало выделенного блока или 0
указать, что нет доступного непрерывного блока запрошенного размера. Если непрерывный блок доступного размера доступен где-либо в адресном пространстве, вы должны выделить его!
Вы должны убедиться, что никакие два выделенных блока не перекрываются.
Освобождает
Функция освобождения должна принимать адрес начала выделенного блока и, необязательно, также может принимать размер данного блока.
Память, которая была освобождена, снова доступна для выделения. Предполагается, что входной адрес является действительным адресом.
Пример реализации Python
Обратите внимание, что вы можете выбрать любой метод для отслеживания внутреннего состояния; в этом примере экземпляр класса отслеживает это.
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]
счет
Это код гольф; выигрывает самый короткий код в байтах. Вам не нужно беспокоиться об исчерпании памяти для любого внутреннего состояния, требуемого вашим распределителем.
Применяются стандартные петлевые отверстия.
Leaderboard
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
или это может быть эффективным (маленький и эффективный не то же самое), насколько это возможно? : DОтветы:
Руби, 80
Как и в ответе MegaTom, но для хранения состояния используется строка вместо массива. Символ «o» обозначает открытую ячейку, а символ «f» обозначает заполненную. Это позволяет нам использовать относительно лаконичные функции Ruby для работы со строками:
?o*n
инициализирует строку из n "o" s./\B#{?o*n}/
является регулярным выражением, совпадающим с n последовательными символами «о», которые не включают первый символ.sub!
заменяет первое совпадение на n "f" s."#$`"
дает строку слева от совпадения или пустую строку, если совпадения не было, поэтому размер равен либо выделенному индексу, либо 0.Deallocate просто устанавливает обозначенный раздел строки обратно в «o».
источник
JavaScript (ES6), 88
Использование глобальной переменной
_
( очень разреженного массива) для отслеживания.Теперь, как я мог это проверить?
источник
Руби, 135
Имеет глобальный массив для отслеживания того, выделена ли каждая ячейка или нет.
источник
Математика, 152
n
хранить общий размер,l
сохраняет внутреннее состояние. Распределитель будет пытаться выделить сразу за другим разделом выделенной памяти.источник