Codegolf — Автономные Бревна

  • Автор темы PiorieVem
  • Обновлено
  • 22, Oct 2024
  • #1

Проблема"

Определить функцию

 i: 777 
(or other 3 letter name) which when called will log/print/write (whatever is the default for the language in question) both the instruction (as source) and the first argument. In other words:

console.log("i:", i)

Для всех практических целей результат i: 777 would be enough, but in some languages there are very specific reflection libraries for that, and that would be no challenge, so the entire instruction should be outputted.

Вдохновение

Вдохновением для этого послужило обсуждение меня и другого программиста, как раздражает то, что часто (с плохими отладчиками) вы пишете такие вещи, как i=777 j=333 log(i) //outputs: "log(i) 777" log(i+j+1) //outputs: "log(i+j+1) 1111" , next we made a (pretty crazy) javascript (node only) solution (it outputs log а не всю строку исходного кода), которая была на удивление длинной и напомнила мне о код-гольфе и заставила меня задуматься, насколько лучше обстоят дела на других языках (особенно на код-гольфе).

Бонусы

-10%: Нет чтения файлов (кроме компилятора)

ПС. Это мой первый «вопрос» здесь, поэтому не стесняйтесь указывать на любые ошибки, которые я допустил.

#код-гольф

PiorieVem


Рег
09 May, 2013

Тем
83

Постов
197

Баллов
622
  • 26, Oct 2024
  • #2

С (40 -10% = 36) (38 -10% = 34,2)

Обратите внимание, что в C

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 " 
function can only be defined for a specific type. Therefore, this log("i") 777 log("j") 333 log("12*4") 48 log("i*j-4") 258737 «функция» занимает только var i = 777, j = 333; log("i") log("j") log("12*4") log("i*j-4") arguments.

function log(x){console.log('log("'+x+'") '+eval(x))}

Более общее решение определяет, как печатать аргумент в дополнение к самому аргументу:

for ($i=1; $i<10; $i++) { $j=$i+1; $k=$j+1; logg($i+$j+$k); echo "\n"; } /* logg($i+$j+$k); 6 logg($i+$j+$k); 9 logg($i+$j+$k); 12 logg($i+$j+$k); 15 logg($i+$j+$k); 18 logg($i+$j+$k); 21 logg($i+$j+$k); 24 logg($i+$j+$k); 27 logg($i+$j+$k); 30 */

который будет использоваться, например, <?php function logg($v){$b=debug_backtrace()[0];$h=fopen($b['file'],"r");for($i=0;$i<$b['line']&&$l=fgets($h);$i++);echo trim($l)." $v";} or log .

 

MikeSan


Рег
20 Aug, 2005

Тем
71

Постов
218

Баллов
583
  • 26, Oct 2024
  • #3

Питон (65 -10% = 58,5)

Предполагается, что ваш код находится в файле (при вызове в интерактивном интерпретаторе он выдает странный результат):

logg

Он был протестирован на Python 2.7.6.

Пример:

APD

результаты

log ||answer||

С++ 121 71 67 -10% = 60,3

CL-USER> (@ (defmacro @(&whole f &rest r)(let((g(gensym)))`(let((,g(multiple-value-list,@r)))(progn(format t"~s~{ ~a~} "',f,g)(values-list,g)))))) STYLE-WARNING: redefining COMMON-LISP-USER::@ in DEFMACRO (@ (DEFMACRO @ (&WHOLE F &REST R) (LET ((G (GENSYM))) `(LET ((,G (MULTIPLE-VALUE-LIST ,@R))) (PROGN (FORMAT T ,"~s~{ ~a~} " ',F ,G) (VALUES-LIST ,G)))))) @ @ ; actual result

Используется так:

defmacro

Выходы:

CL-USER>(@ (+ 3 2)) ; user input (@ (+ 3 2)) 5 ; printed output 5 ; result of expression CL-USER> (@ (values 3 4)) ; input (@ (VALUES 3 4)) 3 4 ; logging 3 ; first value 4 ; second value CL-USER>(@ (round 3.4)) (@ (ROUND 3.4)) 3 0.4000001 3 ; rounded value 0.4000001 ; delta ||answer||

Ребол3 - 31,5 (35 - 10 %)

Вот простая реализация, сокращенная от @draegtun, которая хорошо работает с числами:

read

Запуск выводит:

prin1

Он может быть гораздо более гибким (для отображения формы нечисловых типов) при 42,3 символа (47–10%)

x

Вывод:

(@ x) ||answer||

Javascript (325)

Я думаю, что это signal function you are looking for:

progn

Использование

@

Выход

log

Длинный код

@

Работает только тогда, когда скрипт помещен внутрь (defmacro @(&whole f &rest r)(let((g(gensym)))`(let((,g(multiple-value-list,@r)))(progn(format t"~s~{ ~a~} "',f,g)(values-list,g))))) tag which is put in set i 777 set j 333 log $i ;#outputs: "log $i 777" log [expr {$i+$j+1}] ;#outputs: "log [expr {$i+$j+1}] 1111" документ, поскольку он отправляет запрос на proc log c {puts [dict g [info fr -1] cmd]\ $c} to get the source code. JSfiddle, F12 Dev Tool Console, embbed julia> @show log(x) log(x) => 1.3862943611198906 файлы не работают, я пытаюсь сделать их доступными везде...

В любом случае, этот вопрос интересен.

 

YEHDNGMgub39


Рег
25 Oct, 2024

Тем
74

Постов
184

Баллов
574
  • 26, Oct 2024
  • #4

Скала - (221 - 10%) = 198,9

Ура макросы! На самом деле они именно для этого и предназначены.

julia> x=4 4 julia> macro log(x) println("log($x) $(log(eval(x)))") end julia> @log(x) log(x) 1.3862943611198906

Читабельная версия:

(macroexpand '(log (+ i j 1))) ;; Prints the following: (let* [x__1__auto__ (+ i j 1)] (clojure.core/println "log(" (quote (+ i j 1)) ")" x__1__auto__))

Пример:

macroexpand

Выходы:

(def i 777) (def j 333) (log i) ;Prints log( i ) 777 (log (+ i j 1)) ;Prints log( (+ i j 1) ) 1111

Поскольку сложение — это вызов метода в Scala, оно возвращает этот подробный синтаксис, но это довольно близко! В некоторых других случаях это также немного более многословно.

 

Estridirestri


Рег
23 Mar, 2004

Тем
72

Постов
208

Баллов
568
  • 26, Oct 2024
  • #5

баш (21 - 10% = 18,9)

Этот:

(defmacro log[x] `(let [x# ~x] (println "log("'~x")" x#)))

Затем используйте $ log(){ echo "$FUNCNAME $@: $(($@))"; } $ i=333 $ j=777 $ log i log i: 333 $ log i+j+1 log i+j+1: 1111 like you would use A=2 B=3 log $((A+B)) :

log $((1+1))

или

echo

Этот метод сделает все, что требуется; В качестве бонуса также будет напечатана некоторая дополнительная информация, но это не запрещено никакими явными правилами.

 

Fleselype61


Рег
17 Mar, 2013

Тем
80

Постов
199

Баллов
609
  • 26, Oct 2024
  • #6

БАШ

Аргументы не передаются с использованием «(...)» в BASH, поэтому я позволил выводу log() соответствовать этому стилю:

log ||answer||

Кложур

alias log=echo;set -v

Гомоконичность имеет свои преимущества!

Чтобы использовать:

log(1) 1 log(x) 3 log(x.+(y)) 7

Давайте посмотрим, что происходит с log(1) val x = 3 log(x) val y = 4 log(x+y) :

import language.experimental.macros def log(p: Any) = macro l def l(c: reflect.macros.Context)(p: c.Expr[Any]) = { import c.universe._ val inputString = show(p.tree) val inputStringExpr = c.Expr[String](Literal(Constant(inputString))) reify { println("log(" + (inputStringExpr.splice) + ") " + p.splice) } } ||answer||

Юлия, 51*0,9=45,9

import language.experimental.macros def log(p:Any)=macro l def l(c:reflect.macros.Context)(p:c.Expr[Any])={import c.universe._;reify{println("log("+(c.Expr[String](Literal(Constant(show(p.tree)))).splice)+") "+p.splice)}}

Альтернатива, но не соответствующая правилам

.js ||answer||

Тсл, 42,3 (47 – 10%)

location.href

Использование:

.html

Редактировать: небольшое улучшение

 

Sergdel


Рег
13 Oct, 2011

Тем
84

Постов
203

Баллов
643
  • 26, Oct 2024
  • #7

Common Lisp - 119,7 (133 -10%)

<script>
  • Именованный <script> function log(msg) { // Get the line number and offset of the line where is function is called var lineInfo = (new Error()).stack.match(/(at log \([\s\S]+?at .+?:)\d+:\d+/m)[0].split('\n')[1].match(/:\d+:\d+/)[0]; var lineNum = lineInfo.split(':')[1]; var charOffset = parseInt(lineInfo.split(':')[2]); // Get the file source request = new XMLHttpRequest(); request.open('GET', window.location.href, true); request.onload = function() { // Get file source code var response = request.responseText; // Get the `log` line var line = response.split('\n')[lineNum - 1]; // Get the `log` statement var logStatement = line.substr(charOffset - 1).split(';')[0]; // Print it console.log(logStatement + ' = ' + msg); }; request.send(); } function doSomething() { var a = 123; log(a); var b = "Hello, I am TrungDQ!"; log(b); } doSomething(); </script> because log(a) = 123 log(b) = Hello, I am TrungDQ! log(message + "!") = ...or just do it out here! — это стандартная функция логарифма, заблокированная по умолчанию (по крайней мере, в SBCL). Также, <script> function log(m){L=(new Error()).stack.match(/(at log \([\s\S]+?at .+?:)\d+:\d+/m)[0].split('\n')[1].match(/:\d+:\d+/)[0];N=L.split(':')[1];C=parseInt(L.split(':')[2]);R=new XMLHttpRequest();R.open('GET',location.href,0);R.onload=function(){console.log(R.response.split('\n')[N-1].substr(C-1).split(';')[0]+' = '+m)};R.send()} function doSomething() { var a = 123; log(a); var b = "Hello, I am TrungDQ!"; log(b); } doSomething(); var message = "...or just do it out here"; log(message + "!"); </script> is only one character long.
  • Действует как function log(m){L=(new Error()).stack.match(/(at log \([\s\S]+?at .+?:)\d+:\d+/m)[0].split('\n')[1].match(/:\d+:\d+/)[0];N=L.split(':')[1];C=parseInt(L.split(':')[2]);R=new XMLHttpRequest();R.open('GET',location.href,0);R.onload=function(){console.log(R.response.split('\n')[N-1].substr(C-1).split(';')[0]+' = '+m)};R.send()} , taking a variable number of arguments, but prints to standard output. In real applications, I would probably log условие с S-выражением вместо вывода вывода, разделенного пробелами.
  • В отличие от существующего решения Clojure, мы в конечном итоге возвращаем значение записанного выражения, так что >> log: func[p] [print[{log}mold p mold/only do p]] >> log [join "4" 4] log [join "4" 4] "44" ;; shows a string >> log [1 + 2] log [1 + 2] 3 can be used whenever log: func[p][print[{log}mold p mold/only do p]] используется.
  • Использование печати >> log: func[p][print[{log[}p{]}do p]] >> i: 777 >> j: 333 >> log [i] log[ 777 ] 777 >> log[i + j + 1] log[ i + j + 1 ] 1111 , which outputs a log: func[p][print[{log[}p{]}do p]] -способная строка. Это полезно при попытке воспроизвести записанные выражения.
  • Обрабатывает все возможные типы (см. ответ C)
  • Учитывает несколько значений
  • Не выдает разные результаты (см. ответ Scala)
  • Работает из файла и из REPL (см. ответ Pyhton)
  • Не требует уловок браузера/интерпретатора (обратная трассировка Python, запрос Javascript)

Примеры результатов:

log(i) 777 log(i+j+1) 1111

И, наконец, если я запишу вышеизложенное int main() { int i = 777; int j = 333; log(i); log(i+j+1); } , I have the ungolfed version:

#include<iostream> #define log(x)std::cout<<"log("#x") "<<(x)<<"\n" ||answer||

138 филиппинских песо

Вы не можете повторно объявить log(x) 1 log(x+i+1) 2 log(x+i+1) 3 log(x+i+1) 4 log(x+i+1) 5 log(x+i+1) 6 log(x+i+1) 7 log(x+i+1) 8 log(x+i+1) 9 log(x+i+1) 10 log(x+i+1) 11 log(foo()) 1 in PHP without using another module ( def foo(): x = 1 log(x) for i in xrange(10): log(x+i+1) return x log(foo()) ) поэтому я использовал import traceback as t def log(x):print t.extract_stack()[-2][3],x instead, i can resubmit with lg2("%f", 3.1415) пример, если необходимо. Это мелочь, но, я думаю, более греховным является то, что предполагается, что функция журнала находится на отдельной строке. Я могу обновить свой ответ в соответствии с комментариями.

lg2("%s", "I'm a string");

пример вывода:

#define lg2(f,x)printf("lg2("#x") "f,x) ||answer||

JavaScript 55 53

#define log(x)printf("log("#x") %d",x)

Использование:

int

Выход:

log

Вы ДОЛЖНЫ использовать двойные кавычки log otherwise it will not work.

 

Nichron


Рег
10 Oct, 2010

Тем
76

Постов
195

Баллов
575
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно