आर में गोल्फ के लिए युक्तियाँ


58

मैं आर सांख्यिकीय भाषा में गोल्फिंग के लिए युक्तियों की तलाश कर रहा हूं। R गोल्फ के लिए शायद एक अपरंपरागत विकल्प है। हालांकि, यह कुछ चीजों को बहुत ही सघनता से करता है (अनुक्रम, यादृच्छिकता, वैक्टर और सूचियां), कई अंतर्निहित कार्यों में बहुत कम नाम हैं , और इसमें एक वैकल्पिक लाइन टर्मिनेटर (;) है। R में कोड गोल्फ समस्याओं को हल करने के लिए आप क्या टिप्स और ट्रिक्स दे सकते हैं?


14
इस सवाल के जवाब आर के लिए एक एंटी-स्टाइलगाइड के रूप में दोगुना हो सकते हैं, यह देखते हुए कि कोड गोल्फ वास्तव में एकमात्र समय है जब आपको इन चीजों का बहुत कुछ करना चाहिए :-)
एंड्रयू ब्रूजा

जवाबों:


44

कुछ सुझाव:

  1. आर में, यह उपयोग करने के लिए अनुशंसा की जाती है <-खत्म हो गया =। गोल्फ के लिए, विपरीत धारण =कम है ...
  2. यदि आप किसी फ़ंक्शन को एक से अधिक बार कॉल करते हैं, तो इसके लिए एक छोटे से उपनाम को परिभाषित करना अक्सर फायदेमंद होता है:

    as.numeric(x)+as.numeric(y)
    
    a=as.numeric;a(x)+a(y)
  3. आंशिक मिलान आपका मित्र हो सकता है, खासकर जब फ़ंक्शंस लिस्ट वापस आती हैं, जिसमें आपको केवल एक आइटम की आवश्यकता होती है। से तुलना rle(x)$lengthsकरेंrle(x)$l

  4. कई चुनौतियों के लिए आपको इनपुट पढ़ने की आवश्यकता होती है। scanअक्सर इसके लिए एक अच्छा फिट है (उपयोगकर्ता एक खाली रेखा को दर्ज करके इनपुट समाप्त करता है)।

    scan()    # reads numbers into a vector
    scan(,'') # reads strings into a vector
  5. जबरदस्ती उपयोगी हो सकती है। t=1से बहुत छोटा है t=TRUE। वैकल्पिक रूप से, switchआप कीमती पात्रों को भी बचा सकते हैं, लेकिन आप 0,1 के बजाय 1,2 का उपयोग करना चाहेंगे।

    if(length(x)) {} # TRUE if length != 0
    sum(x<3)         # Adds all the TRUE:s (count TRUE)
  6. यदि कोई फ़ंक्शन किसी जटिल चीज़ की गणना करता है और आपको उसी मूल मूल्य के आधार पर कई अन्य प्रकार की गणनाओं की आवश्यकता होती है, तो यह अक्सर या तो फायदेमंद होता है: ए) इसे छोटे कार्यों में तोड़ देता है, बी) एक सूची के रूप में आपके द्वारा आवश्यक सभी परिणामों को वापस करें, या c) इसमें फ़ंक्शन के तर्क के आधार पर विभिन्न प्रकार के मान हैं।

  7. जैसा कि किसी भी भाषा में, यह अच्छी तरह से जानते हैं - आर के हजारों कार्य हैं, शायद कुछ ऐसा है जो बहुत कम पात्रों में समस्या को हल कर सकता है - यह जानने के लिए कि कौन सी चाल है!

कुछ अस्पष्ट लेकिन उपयोगी कार्य:

sequence
diff
rle
embed
gl # Like rep(seq(),each=...) but returns a factor

कुछ अंतर्निहित डेटा सेट और प्रतीक:

letters     # 'a','b','c'...
LETTERS     # 'A','B','C'...
month.abb   # 'Jan','Feb'...
month.name  # 'January','Feburary'...
T           # TRUE
F           # FALSE
pi          # 3.14...

22
  1. के साथ एक पैकेज आयात करने के बजाय library, का उपयोग करके पैकेज से चर को पकड़ो ::। अनुसरण की तुलना करें:

    library(splancs);inout(...)
    splancs::inout(...)

    बेशक, यह केवल तभी मान्य है जब पैकेज से किसी एक फ़ंक्शन का उपयोग किया जाता है।

  2. यह तुच्छ है, लेकिन जब किसी फ़ंक्शन को अलियासिंग करने के लिए टॉमी की चाल का उपयोग करने के लिए अंगूठे का एक नियम है: यदि आपके फ़ंक्शन का नाम लंबाई है mऔर इसका उपयोग nबार किया जाता है, तो उपनाम केवल तभी m*n > m+n+3(क्योंकि जब उपनाम आपके द्वारा खर्च किए गए को परिभाषित करता है m+3और तब भी आप खर्च करते हैं 1 हर बार उपनाम का उपयोग किया जाता है)। एक उदाहरण:

    nrow(a)+nrow(b)     # 4*2 < 4+3+2
    n=nrow;n(a)+n(b)
    length(a)+length(b) # 6*2 > 6+3+2
    l=length;l(a)+l(b)
  3. कार्यों के साइड-इफेक्ट के रूप में जोर:

    • उपयोग करने के बजाय as.integer, वर्ण तार का उपयोग करके पूर्णांक के लिए मजबूर किया जा सकता है ::

      as.integer("19")
      ("19":1)[1] #Shorter version using force coercion.
    • पूर्णांक, सांख्यिक, इत्यादि का उपयोग pasteकरने के लिए इसी तरह से वर्ण का उपयोग किया जा सकता है as.character:

      as.character(19)
      paste(19) #Shorter version using force coercion.

6
पुन :: 3 टिप, el("19":1)एक बाइट से भी छोटा है।
JayCe

19

कुछ बहुत ही विशिष्ट गोल्फ युक्तियाँ:

  • यदि आपको एक वेक्टर की लंबाई निकालने की आवश्यकता है, sum(x|1)तो length(x)जब तक xसंख्यात्मक, पूर्णांक, जटिल या तार्किक है, तब तक कम है ।
  • यदि आप एक वेक्टर के अंतिम तत्व को निकालने के लिए की जरूरत है, यह सस्ता हो सकता है (यदि संभव हो) वेक्टर आरंभ करने के लिए पीछे की ओर का उपयोग कर rev()और फिर बुला x[1]के बजाय x[length(x)](या ऊपर टिप का उपयोग कर, x[sum(x|1)]) (या tail(x,1)--- धन्यवाद ग्यूसेप!)। इस पर थोड़ी भिन्नता (जहां दूसरा-अंतिम तत्व वांछित था) को यहां देखा जा सकता है । यहां तक ​​कि अगर आप वेक्टर को पीछे की तरफ से इनिशियलाइज़ नहीं कर सकते हैं, तब rev(x)[1]भी इससे छोटा है x[sum(x|1)](और यह कैरेक्टर वैक्टर के लिए भी काम करता है)। कभी-कभी आपको इसकी आवश्यकता भी नहीं होती है rev, उदाहरण के लिए n:1इसके बजाय का उपयोग करना 1:n
  • (जैसा देख गया यहां है )। यदि आप किसी मैट्रिक्स में डेटा फ़्रेम को ले जाना चाहते हैं, तो उपयोग न करें as.matrix(x)। प्रपोजल का बदला, ले लो t(t(x))

  • ifएक औपचारिक कार्य है। उदाहरण के लिए,"if"(x<y,2,3)if(x<y)2 else 3 (की तुलना में कम है हालांकि 3-(x<y)छोटा है)। यह केवल पात्रों को बचाता है यदि आपको इसे इस तरह तैयार करने के लिए ब्रेसिज़ की एक अतिरिक्त जोड़ी की आवश्यकता नहीं है, जो आप अक्सर करते हैं।

  • अंकीय वस्तुओं की गैर-समानता का परीक्षण करने के लिए, if(x-y)की तुलना में कम है if(x!=y)। किसी भी गैर-संख्यात्मक अंक को माना जाता हैTRUE । यदि आप समानता का परीक्षण कर रहे हैं, कहते हैं, if(x==y)a else bतो if(x-y)b else aइसके बजाय प्रयास करें । पिछला बिंदु भी देखें।

  • फ़ंक्शन elतब उपयोगी होता है जब आपको किसी सूची से आइटम निकालने की आवश्यकता होती है। सबसे आम उदाहरण शायद हैstrsplit : el(strsplit(x,""))की तुलना में एक कम बाइट है strsplit(x,"")[[1]]

  • (जैसा कि यहां इस्तेमाल किया गया है ) वेक्टर एक्सटेंशन आपको पात्रों को बचा सकता है: यदि वेक्टर vकी लंबाई है nतो आप v[n+1]बिना किसी त्रुटि के असाइन कर सकते हैं । उदाहरण के लिए, यदि आप पहले दस फैक्टरियों को प्रिंट करना चाहते थे जो आप कर सकते थे: v=1;for(i in 2:10)v[i]=v[i-1]*iबजाय v=1:10:for(...)(हालांकि हमेशा की तरह, एक और बेहतर, तरीका है cumprod(1:10):)

  • कभी-कभी, पाठ आधारित चुनौतियों (विशेष रूप से 2-डी वाले) के लिए, इसके plotबजाय पाठ के लिए आसान catहै। यह नियंत्रित pch=करने के लिए plotकि कौन से वर्ण प्लॉट किए गए हैं। pc=एक बाइट को बचाने के लिए इसे छोटा किया जा सकता है (जो चेतावनी भी देगा)। यहाँ उदाहरण है

  • एक नंबर का फर्श लेने के लिए, उपयोग न करें floor(x)x%/%1इसके बजाय उपयोग करें ।

  • यह जांचने के लिए कि क्या संख्यात्मक या पूर्णांक वेक्टर के तत्व सभी समान हैं, आप अक्सर sdकुछ क्रियाओं जैसे कि का उपयोग कर सकते हैं all.equal। यदि सभी तत्व समान हैं, तो उनका मानक विचलन शून्य है ( FALSE) और मानक विचलन सकारात्मक है (TRUE )। यहाँ उदाहरण है

  • कुछ कार्य जिन्हें आप पूर्णांक इनपुट की आवश्यकता की उम्मीद करेंगे, वास्तव में नहीं होते हैं। उदाहरण के लिए, seq(3.5)वापस आ जाएगा 1 2 3( :ऑपरेटर के लिए भी यही सच है )। इससे कॉल से बचा जा सकता है floorऔर कभी-कभी इसका मतलब है कि आप /इसके बजाय उपयोग कर सकते हैं %/%


1
tail(v,1)rev(v)[1]"सरणी के अंतिम तत्व" के रूप में अच्छी तरह से गोल्फ टिप के लिए एक ही लंबाई है ।
ग्यूसेप

read.csv(t="a,b,c",,F)से छोटा है el(strsplit("a,b,c",","))
जे। सेप

18
  1. बिल्डरों का दुरुपयोग Tऔर F। डिफ़ॉल्ट रूप से, वे मूल्यांकन करते हैं TRUEऔर FALSE, जो स्वचालित रूप से संख्यात्मक 1और में परिवर्तित हो सकते हैं 0, और उन्हें फिर से परिभाषित किया जा सकता है। इसका मतलब यह है कि आप एक काउंटर (जैसे प्रारंभ करने की जरूरत नहीं है i=0... i=i+1), तो आप सिर्फ उपयोग कर सकते हैं Tया F(और के लिए सीधे कूद की जरूरत के रूप मेंF=F+1 बाद में)।
  2. याद रखें कि फ़ंक्शंस अंतिम ऑब्जेक्ट को कहते हैं और एक स्पष्ट return()कॉल की आवश्यकता नहीं है ।
  3. आमतौर पर उपयोग किए जाने वाले कार्यों के लिए लघु उपनामों को परिभाषित करना महान है, जैसे कि p=paste। यदि आप एक फ़ंक्शन का उपयोग करते हैं, और वास्तव में दो तर्कों के साथ, यह संभव है कि एक infixing उपनाम आपको कुछ बाइट्स बचाएगा। Infixing उपनामों से घिरा होना चाहिए %। उदाहरण के लिए:

    `%p%`=paste

    और बाद में x%p%y, जो 1 बाइट से छोटा है p(x,y)। हालांकि, इनसिक्योर उर्फ ​​परिभाषा 4-बाइट्स की तुलना में गैर-इनफ़िक्सिंग की तुलना में अधिक लंबी है p=paste, इसलिए आपको यह सुनिश्चित करना होगा कि यह इसके लायक है।


9
आप आदिम फ़ंक्शंस का उपयोग कर सकते हैं और आप कई बाइट्स बचा सकते हैं:`+`=paste; x+y
मैस्किन्स

14

का उपयोग करना if, ifelseऔर`if`

यदि आर-गोल्फ-इष्टतम समाधान में बयान बहुत भिन्न हो सकते हैं, तो कई तरीके हैं।

मूल बातें

  1. ifनियंत्रण प्रवाह के लिए है। यह सदिश नहीं है, अर्थात केवल लंबाई की स्थितियों का मूल्यांकन कर सकता है 1. इसके elseलिए (वैकल्पिक रूप से) एक और मूल्य वापस करना होगा।
  2. ifelseएक समारोह है। यह वेक्टरकृत है, और मनमानी लंबाई के मूल्यों को वापस कर सकता है। इसका तीसरा तर्क (दूसरा मूल्य) अनिवार्य है। *
  3. `if`के रूप में एक ही वाक्यविन्यास के साथ एक समारोह है ifelse। यह सदिश नहीं है, और न ही कोई वापसी तर्क अनिवार्य है।

* यह तकनीकी रूप से अनिवार्य नहीं है; ifelse(TRUE,x)ठीक काम करता है, लेकिन यह एक त्रुटि फेंकता है यदि तीसरा तर्क खाली है और स्थिति का मूल्यांकन करता है FALSE। तो यह केवल उपयोग करने के लिए सुरक्षित है यदि आप सुनिश्चित हैं कि स्थिति हमेशा हैTRUE , और यदि यह मामला है, तो आप एक इफ-स्टेटमेंट के साथ भी क्यों परेशान कर रहे हैं?

उदाहरण

ये सभी बराबर हैं:

if(x)y else z # 13 bytes
ifelse(x,y,z) # 13 bytes
`if`(x,y,z)   # 11 bytes

ध्यान दें कि elseयदि आप कोड में सीधे तार का उपयोग कर रहे हैं तो आसपास के रिक्त स्थान की आवश्यकता नहीं है:

if(x)"foo"else"bar"   # 19 bytes
ifelse(x,"foo","bar") # 21 bytes
`if`(x,"foo","bar")   # 19 bytes

अब तक, `if`विजेता के रूप में दिखता है, जब तक कि हमारे पास वेक्टरकृत इनपुट नहीं है। लेकिन उन मामलों के बारे में जहां हम दूसरी स्थिति की परवाह नहीं करते हैं? कहो कि हम केवल कुछ कोड निष्पादित करना चाहते हैं यदि शर्त है TRUE। अकेले कोड की एक पंक्ति के लिए, ifआमतौर पर सबसे अच्छा होता है:

if(x)z=f(y)         # 11 bytes
ifelse(x,z<-f(y),0) # 19 bytes
`if`(x,z<-f(y))     # 15 bytes

कोड की कई पंक्तियों के लिए, ifअभी भी विजेता है:

if(x){z=f(y);a=g(y)}        # 20 bytes
ifelse(x,{z=f(y);a=g(y)},0) # 27 bytes
`if`(x,{z=f(y);a=g(y)})     # 23 bytes

इस बात की भी संभावना है कि हम किसी अन्य शर्त के बारे में क्या सोचते हैं, और जहाँ हम मान वापस करने के बजाय मनमाने कोड को निष्पादित करना चाहते हैं। इन मामलों में, ifऔर `if`बाइट गिनती में बराबर हैं।

if(x)a=b else z=b   # 17 bytes
ifelse(x,a<-b,z<-b) # 19 bytes
`if`(x,a<-b,z<-b)   # 17 bytes

if(x){z=y;a=b}else z=b   # 22 bytes
ifelse(x,{z=y;a=b},z<-b) # 24 bytes
`if`(x,{z=y;a=b},z<-b)   # 22 bytes

if(x)a=b else{z=b;a=y}   # 22 bytes
ifelse(x,a<-b,{z=b;a=y}) # 24 bytes
`if`(x,a<-b,{z=b;a=y})   # 22 bytes

if(x){z=y;a=b}else{z=b;a=y}   # 27 bytes
ifelse(x,{z=y;a=b},{z=b;a=y}) # 29 bytes
`if`(x,{z=y;a=b},{z=b;a=y})   # 27 bytes

सारांश

  1. ifelseजब आपके पास लंबाई> 1 का इनपुट हो तो उपयोग करें ।

  2. यदि आप कोड की कई पंक्तियों को निष्पादित करने के बजाय एक साधारण मान लौटा रहे हैं, तो `if`फ़ंक्शन का उपयोग करना संभवतः पूर्ण if... elseकथन से कम है ।

  3. यदि आप केवल एक ही मूल्य चाहते हैं TRUE, का उपयोग करें if

  4. मनमाना कोड निष्पादित करने के लिए, `if`और ifआमतौर पर बाइट गिनती के संदर्भ में समान हैं; मैं ifमुख्य रूप से सलाह देता हूं क्योंकि यह पढ़ना आसान है।


1
अच्छा! बहुत अच्छी तुलना, +1!
बिलीवोब

13
  1. आप एक फ़ंक्शन के लिए एक तर्क के रूप में एक साथ आपूर्ति करते हुए वर्तमान परिवेश में एक चर असाइन कर सकते हैं:

    sum(x <- 4, y <- 5)
    x
    y
  2. यदि आप एक सब्मिट कर रहे हैं data.frameऔर आपकी स्थिति उसके कई कॉलमों पर निर्भर करती है, तो आप (या ) data.frameका उपयोग करके नाम को दोहराने से बच सकते हैं ।withsubset

    d <- data.frame(a=letters[1:3], b=1:3, c=4:6, e=7:9)
    with(d, d[a=='b' & b==2 & c==5 & e==8,])

    के बजाय

    d[d$a=='b' & d$b==2 & d$c==5 & d$e==8,]

    बेशक, यह केवल पात्रों को बचाता है यदि आपके संदर्भ data.frameकी लंबाई लंबाई से अधिक हैwith(,)

  3. if...elseब्लॉक अंतिम विवरण के मूल्य को वापस कर सकते हैं जिसमें कभी ब्लॉक का हिस्सा निष्पादित होता है। उदाहरण के लिए, के बजाय

    a <- 3
    if (a==1) y<-1 else
    if (a==2) y<-2 else y<-3

    तुम लिख सकते हो

    y <- if (a==1) 1 else 
         if (a==2) 2 else 3

4
केवल (1) के बारे में सावधानी यह है कि जब आप ऐसा करते हैं कि आप इसे क्रम से पारित कर रहे हैं नामांकित तर्क द्वारा नहीं। अगर है f <- function(a,b) cat(a,b), तो f(a <- 'A', b <- 'B')जैसा है वैसा नहीं है f(b <- 'B', a <- 'A')
अरी बी। फ्रीडमैन

11

निहित प्रकार रूपांतरण

फ़ंक्शंस as.character, as.numericऔर as.logicalबाइट भारी हैं। चलो उन्हें नीचे ट्रिम करें।

संख्यात्मक से तार्किक में रूपांतरण (4 बाइट्स)

मान लीजिए xकि एक संख्यात्मक वेक्टर है। तार्किक नहीं ऑपरेटर का उपयोग करना, !संख्यात्मक को तार्किक वेक्टर, जहां और नॉनज़ेरो मान हैं , को पुन: व्यवस्थित करता 0है । फिर उस का विरोध करता है।FALSETRUE!

x=!x

x=0:3;x=!xलौटता है TRUE FALSE FALSE FALSE

संख्यात्मक या तार्किक से चरित्र में रूपांतरण (7 बाइट्स)

यह एक मजेदार है। ( इस ट्वीट से )

x[0]=''

देखता है कि आप वेक्टर xको अपडेट कर रहे हैं '', जो कक्षा का है character। इसलिए यह xकक्षा में प्रवेश करता है characterइसलिए यह नए डेटा बिंदु के साथ संगत है। इसके बाद, यह डाल करने के लिए चला जाता है ''उचित जगह में ... लेकिन सूचकांक 0मौजूद नहीं है (यह चाल भी साथ काम करता है Inf, NaN, NA, NULL, और इतने पर)। परिणामस्वरूप, xकेवल कक्षा में ही संशोधित किया जाता है।

x=1:3;x[0]=''लौटता है "1" "2" "3", x=c(TRUE,FALSE);x[0]=''लौटता है "TRUE" "FALSE"

यदि आपके पास अपने कार्यक्षेत्र में पहले से परिभाषित एक चरित्र वस्तु है, तो आप ''बाइट को बचाने के बजाय इसका उपयोग कर सकते हैं । उदाहरण के लिए,x[0]=y ,!

कुछ शर्तों के तहत संख्यात्मक या तार्किक से चरित्र में रूपांतरण (6 बाइट्स)

J.Doe ने टिप्पणियों में छह-बाइट समाधान का उल्लेख किया:

c(x,"")

अगर यह काम करता है x परमाणु है और यदि आप इसे एक समारोह में पारित करने का इरादा रखते हैं जिसमें परमाणु वेक्टर की आवश्यकता होती है। (फ़ंक्शन तर्क के तत्वों की अनदेखी के बारे में चेतावनी फेंक सकता है।)

तार्किक से संख्यात्मक में रूपांतरण (4 बाइट्स)

आप ऊपर से फंकी इंडेक्सिंग ट्रिक का उपयोग कर सकते हैं (जैसे x[0]=3), लेकिन वास्तव में एक तेज़ तरीका है:

x=+x

सकारात्मक संचालक वेक्टर को एक संख्यात्मक वेक्टर के रूप में पुन: प्रस्तुत करता है, इसलिए यह TRUE FALSEबन जाता है 1 0


आपकी आखिरी चाल हो सकता है x=+xरखने के लिए TRUEके रूप में 1
Giuseppe

@Giuseppe ओह, duh, बिल्कुल! धन्यवाद, अब अपडेट किया गया।
rturnbull

संख्यात्मक या तार्किक से चरित्र में रूपांतरण। आप उपयोग कर सकते हैं c(x,""), तो xपरमाणु है, बशर्ते कि आप तो उपयोग करने के लिए जा रहे हैं xएक समारोह है कि केवल पहला तत्व के बारे में परवाह करता है (यह शिकायत कर सकते हैं) में। यह 1 बाइट से सस्ता है x[0]="";
जे। सेप

10

आर में डू-लूप करते हैं

कभी-कभी, मैं अपने आप को कामना करता हूं कि आर का do-whileलूप था, क्योंकि:

 some_code
while(condition){
 some_code # repeated
}

अब तक बहुत लंबा और बहुत गैर-गोल्फ है। हालाँकि, हम इस व्यवहार को पुनर्प्राप्त कर सकते हैं और {फ़ंक्शन की शक्ति के साथ कुछ बाइट्स को बंद कर सकते हैं ।

{और आर में (प्रत्येक .Primitiveकार्य हैं।

उनके लिए प्रलेखन पढ़ता है:

प्रभावी रूप से, (शब्दार्थ पहचान के समतुल्य है function(x) x, जबकि {थोड़ा और दिलचस्प है, उदाहरण देखें।

और मूल्य के तहत,

के लिए (, तर्क का मूल्यांकन करने का परिणाम है। इसमें दृश्यता सेट है, इसलिए शीर्ष स्तर पर उपयोग किए जाने पर ऑटो-प्रिंट होगा।

के लिए {, अंतिम अभिव्यक्ति के परिणाम का मूल्यांकन किया गया । इसमें अंतिम मूल्यांकन की दृश्यता है।

(महत्व दिया)

अच्छा तो इसका क्या मतलब है? इसका मतलब है कि एक लूप जबकि लूप उतना ही सरल है

while({some_code;condition})0

क्योंकि {}प्रत्येक के अंदर के भावों का मूल्यांकन किया जाता है, और केवल अंतिम एक को लौटाया जाता है {, जिससे हमें some_codeलूप में प्रवेश करने से पहले मूल्यांकन करने की अनुमति मिलती है , और यह हर बार (या सत्य) चलता conditionहै TRUE0कई 1-बाइट भाव है कि 'असली' शरीर रूपों में से एक है whileपाश।


10
  1. outerदो सूचियों के सभी संयोजनों के लिए एक मनमाना फ़ंक्शन लागू करने का दुरुपयोग करें । पहले आर्ग्स द्वारा अनुक्रमित जे, जे के साथ एक मैट्रिक्स की कल्पना करें, फिर आप प्रत्येक जोड़ी के लिए एक मनमाना फ़ंक्शन (i, j) को परिभाषित कर सकते हैं।

  2. के Mapलिए एक शॉर्टकट के रूप में उपयोग करें mapply। मेरा दावा है कि mapplyउन स्थितियों में लूप से सस्ता है, जहां आपको सूचकांक तक पहुंचने की आवश्यकता है। आर में सूची संरचना का दुरुपयोग unlistमहंगा है। methods::elआपको पहले तत्व को सस्ते में अनलिस्ट करने की अनुमति देता है। मूल रूप से सूची समर्थन के साथ कार्यों का उपयोग करने का प्रयास करें।

  3. do.callमनमाना आदानों के साथ फ़ंक्शन कॉल को सामान्य करने के लिए उपयोग करें ।

  4. Reduceकोड गोल्फ के लिए संचित args बेहद मददगार है।

  5. के साथ लाइन द्वारा सांत्वना लाइन के साथ लिखना cat(blah, "\n")सस्ता है write(blah, 1)। "\ N" के साथ हार्ड कोडित तार कुछ स्थितियों में सस्ते हो सकते हैं।

  6. यदि कोई फ़ंक्शन डिफ़ॉल्ट तर्कों के साथ आता है, तो आप सीधे n-वें तर्क को निर्दिष्ट करने के लिए फ़ंक्शन (,, n-arg) का उपयोग कर सकते हैं। उदाहरण: seq(1, 10, , 101)कुछ कार्यों में, आंशिक तर्क मिलान का समर्थन किया जाता है। उदाहरण: seq(1, 10, l = 101)

  7. यदि आपको स्ट्रिंग हेरफेर से जुड़ी कोई चुनौती दिखाई देती है, तो बस बैक बटन दबाएं और अगला प्रश्न पढ़ें। strsplitआर गोल्फ को बर्बाद करने के लिए एकल रूप से जिम्मेदार है।

अब 2018 के कुछ नए खोजे गए सुझावों के लिए

  1. A[cbind(i,j)] = zमैट्रिसेस में हेरफेर करने का एक अच्छा तरीका हो सकता है। i, j, zसही लंबाई के साथ वैक्टर के रूप में आपके द्वारा डिज़ाइन किए गए यह ऑपरेशन बहुत ही बाइट कुशल है । आप वास्तविक सूचकांक / असाइन फ़ंक्शन को कॉल करके और भी अधिक बचत कर सकते हैं "[<-"(cbind(i,j), z)। कॉलिंग का यह तरीका संशोधित मैट्रिक्स लौटाता है।

  2. \nलाइन ब्रेक के लिए एक नई लाइन का उपयोग करें ।

  3. लाइन काउंट को निचोड़ने से आप बाइट बचा सकते हैं। इन-लाइन असाइनमेंट lapply(A<-1:10,function(y) blah)और फंक्शन आर्ग्स असाइनमेंट function(X, U = X^2, V = X^3)ऐसा करने के तरीके हैं।

  4. तो "[<-"R में एक फ़ंक्शन है (और SO पर मेरे प्राचीन प्रश्न से संबंधित है )! यह अंतर्निहित कार्यप्रणाली है जैसे संचालन के लिए जिम्मेदार x[1:5] = rnorm(5)। फ़ंक्शन को नाम से कॉल करने की नीरस संपत्ति आपको संशोधित वेक्टर वापस करने की अनुमति देती है। आदेश में शब्द "[<-"(x, 1:5, normr(5))लगभग वही काम करता है जो ऊपर दिए गए कोड को छोड़कर संशोधित एक्स लौटाता है। संबंधित "लंबाई <-", "नाम <-", "कुछ भी <-" सभी संशोधित आउटपुट लौटाते हैं


1
मुझे लगता है कि इसका उपयोग "[<-"अपने "टिप्स" जवाब के योग्य है, क्योंकि यह संशोधित सरणी / मैट्रिक्स / जो कुछ भी लौटाएगा।
ग्यूसेप

10
  1. इन-लाइन मूल्यों को सहेजें : अन्य लोगों ने उल्लेख किया है कि आप मूल्यों को क्रम में पारित कर सकते हैं और उन्हें अन्यत्र उपयोग के लिए असाइन कर सकते हैं, अर्थात

    sum(x<- 1:10, y<- seq(10,1,2))

    हालाँकि, आप उसी पंक्ति में उपयोग के लिए मानों को इनलाइन भी सहेज सकते हैं !

    उदाहरण के लिए

    n=scan();(x=1:n)[abs(x-n/2)<4]

    से पढ़ता है stdin, एक चर बनाता है x=1:n, फिर xउस मूल्य का उपयोग करने में अनुक्रमित करता है x। यह कभी-कभी बाइट्स बचा सकता है।

  2. खाली वेक्टर के लिए उपनाम आप खाली वेक्टर के{} रूप में उपयोग कर सकते हैं c()क्योंकि वे दोनों वापस लौटते हैं NULL

  3. आधार रूपांतरणn आधार 10 में पूर्णांक अंकों के लिए , उपयोग करें n%/%10^(0:nchar(n))%%10। यह एक अनुगामी शून्य को छोड़ देगा, इसलिए यदि यह आपके लिए महत्वपूर्ण है, तो इसका उपयोग करें n%/%10^(1:nchar(n)-1)%%10क्योंकि यह सरणी अनुक्रमण से छोटा है। इसका उपयोग करके अन्य आधारों के लिए अनुकूलित किया जा सकता हैfloor(log(n,b))+1 बजाय का हैnchar(n)

  4. उपयोग करना seqऔर: : 1:length(l)(या 1:sum(x|1)) का उपयोग करने के बजाय , आप तब तक उपयोग कर सकते हैं seq(l)जब तक कि lयह 1 से अधिक की लंबाई listया vector1 है, क्योंकि यह चूक करता है seq_along(l)। यदि lसंभावित रूप से लंबाई हो सकती है 1, seq(a=l)तो चाल चलेगी।

    इसके अतिरिक्त, :(एक चेतावनी के साथ) अपने तर्कों के पहले तत्व का उपयोग करेगा।

  5. गुण निकाला जा रहा है का उपयोग करते हुए c()एक पर array(याmatrix ) उसी के समान होगा as.vector; यह आम तौर पर गैर-नाम विशेषताओं को हटा देता है।

  6. फैक्टरियल का उपयोग करने gamma(n+1)की तुलना में कम है factorial(n)और factorialइसे परिभाषित किया गया हैgamma(n+1) वैसे भी है।

  7. सिक्का फ़्लिप करना जब किसी यादृच्छिक कार्य को करने की आवश्यकता होती है, उस समय का 50% उपयोग करने rt(1,1)<0से कम होता हैrunif(1)<0.5 तीन बाइट्स है।

  8. तत्वों को निकालना / बाहर निकालना head और tailअक्सर किसी सरणी के पहले / अंतिम कुछ तत्वों को निकालने के लिए उपयोगी होते हैं; head(x,-1)यदि आप पहले से ही लंबाई नहीं जानते हैं, तो सभी अंतिम तत्व निकालते हैं और नकारात्मक अनुक्रमण का उपयोग करने से छोटा होता है:

    head(x,-1)
    x[-length(x)]
    x[-sum(x|1)]


@ जे। अपने ही पद के योग्य हैं, मुझे लगता है! शायद "विकल्प" के शीर्षक के साथ rep। अन्य युक्तियों के सवालों में प्रति उत्तर एक टिप का प्रतिबंध है, जो मैं इस प्रश्न के लिए भी तहे दिल से समर्थन करता हूं! इसके अलावा, दो बाइट्स की 1:n*0तुलना में कम है Im(1:n), जिसका मतलब है कि आपकी दूसरी चाल भी हो सकती है x+0*-n:n:-)
Giuseppe

1
@ J.Doe या इससे भी बेहतर, उपयोग के मामले के आधार पर !1:nभी nशून्य की एक सरणी है ; MATL / MATLAB युक्तियों के सवाल का श्रेय (शायद लुइस मेंडो) को उस एक के लिए, हालांकि।
ग्यूसेप

धन्यवाद, @Giuseppe! क्या मैं आपको यह पोस्ट बनाने का सुझाव दे सकता हूं, क्योंकि मैं आपके अच्छे विचारों से प्रतिष्ठा नहीं लेना चाहता।
जे।

@ जे। ओह, मुझे कोई आपत्ति नहीं है। हमेशा अन्य आर गोल्फरों को अधिक दृश्यता प्राप्त करने के लिए अच्छा है; मुझे लगता है कि यह कहना उचित है कि मैं इस समय एक बहुत प्रसिद्ध संस्था हूं! आप काफी प्रभावशाली सुधारों का सुझाव देते हुए जा रहे हैं, इसलिए रेप (दंड का इरादा नहीं) करें और अच्छे काम को जारी रखें :-)
Giuseppe

1
(log(i,b)%/%1):0)इसके बजाय नहीं floor(log(n,b))+1?
ASCII- केवल

8

कुछ बुनियादी अवधारणाएँ लेकिन कुछ उपयोगी होनी चाहिए:

  1. नियंत्रण प्रवाह कथनों में आप दुरुपयोग कर सकते हैं कि शून्य के बराबर किसी भी संख्या का मूल्यांकन नहीं किया जाएगा TRUE, उदाहरण के लिए: if(x)के बराबर है if(x!=0)। इसके विपरीत, if(!x)के बराबर है if(x==0)

  2. जब :(जैसे 1:5) दृश्यों का उपयोग करते हुए उत्पन्न करते हैं, तो इस तथ्य का दुरुपयोग किया जा सकता है कि प्रतिपादक ऑपरेटर ^एकमात्र ऑपरेटर है, जिसके पास :-ओपरेटर (जैसा कि विरोध किया गया है +-*/) पर पूर्ववर्तीता है ।

    1:2^2 => 1 2 3 4 

    जो आपको दो बाइट्स को कोष्ठक पर सहेजता है, जिसे आप सामान्य रूप से उस स्थिति में उपयोग करना चाहते हैं जब आप n x nमैट्रिक्स ( 1:n^2) या किसी अन्य पूर्णांक के तत्वों पर लूप करना चाहते थे जिसे घातीय संकेतन ( 1:10^6) का उपयोग करके छोटे तरीके से व्यक्त किया जा सकता है ।

  3. एक संबंधित ट्रिक का उपयोग +-*/वेक्टर ऑपरेशन पर भी किया जा सकता है , हालाँकि आमतौर पर सबसे अधिक उपयोग में आता है +-:

    for(i in 1:(n+1)) can instead be written as for(i in 0:n+1)

    यह काम करता है क्योंकि +1वेक्टरकृत होता है और वेक्टर 1के 0:nपरिणामस्वरूप प्रत्येक तत्व को जोड़ता है 1 2 ... n+1। इसी तरह 0:(n+1) == -1:n+1आपको एक बाइट भी बचाता है।

  4. छोटे कार्यों को लिखते समय (जो एक पंक्ति पर व्यक्त किया जा सकता है), एक घुमाने वाले घुंघराले ब्रैकेट पर दो बाइट्स को बचाने के लिए चर असाइनमेंट का दुरुपयोग कर सकता है {...}:

    f=function(n,l=length(n))for(i in 1:l)cat(i*l,"\n")
    f=function(n){l=length(n);for(i in 1:l)cat(i*l,"\n")}

    ध्यान दें कि यह हमेशा कुछ चुनौतियों के नियमों का पालन नहीं कर सकता है।


बस थोड़ा सा सुधार: ^सदिशीकृत है, यह सिर्फ इतना है कि इस पर पूर्वता है :(यानी इसे :तब तक निष्पादित किया जाता है जब तक कि ब्रैकेट स्पष्ट रूप से विपरीत संकेत नहीं देते हैं, ?Syntaxबाइनरी और यूनिरी ऑपरेटरों की पूर्वता के सटीक क्रम के लिए देखें )। उसी बाइनरी के लिए जाता है, +-/*जिसमें :आपकी चाल n ° 3 की तुलना में कम पूर्वता है ।
प्लेनैपस

@plannapus स्पष्ट करने के लिए धन्यवाद। शब्दांकन अपडेट किया गया।
बिलीवोब

7

ऑपरेटरों के अर्थ को बदलें

आर ऑपरेटर केवल ऐसे कार्य हैं जो पार्सर द्वारा विशेष उपचार प्राप्त करते हैं। उदाहरण के लिए <वास्तव में दो चर का एक कार्य है। कोड की ये दो लाइनें एक ही काम करती हैं:

x < 3
`<`(x, 3) 

आप किसी अन्य फ़ंक्शन को किसी ऑपरेटर को पुन: असाइन कर सकते हैं, और पार्सर अभी भी यह काम करेगा, जिसमें ऑपरेटर पूर्वता का सम्मान करना शामिल है, लेकिन अंतिम फ़ंक्शन कॉल मूल के बजाय नया होगा। उदाहरण के लिए:

`<`=rep

अब कोड की इन दो पंक्तियों का मतलब एक ही काम करता है:

rep("a", 3)
"a"<3

और पूर्वता का सम्मान किया जाता है, जिसके परिणामस्वरूप चीजें होती हैं

"a"<3+2
#[1] "a" "a" "a" "a" "a"

इस उत्तर के उदाहरण के लिए देखें , और ऑपरेटर पूर्वता पृष्ठ भी । साइड इफेक्ट के रूप में, आपका कोड उतना ही गूढ़ हो जाएगा जितना कि एक गोल्फ भाषा में लिखा गया है।

कुछ ऑपरेटर पसंद करते हैं +और -या तो एक या दो मापदंडों को स्वीकार कर सकते हैं, इसलिए आप निम्न चीजें भी कर सकते हैं:

`-`=sample
set.seed(1)
-5  # means sample(5)
#[1] 2 5 4 3 1
5-2 # means sample(5, 2)
#[1] 5 4

उदाहरण के लिए देखें यह उत्तर

दो-बाइट, तीन-तर्क ऑपरेटर के रूप में उपयोग करने के लिए इस उत्तर को भी देखें [


2
यह rturnbull की युक्तियों पर एक टिप्पणी है, लेकिन मुझे लगता है कि हमें "प्रति उत्तर एक टिप" नियम लागू करना शुरू करने की आवश्यकता है क्योंकि यह बहुत ही अजीब है कि मुझे यहां आने पर जिस चीज की आवश्यकता है उसे ढूंढना मुश्किल है।
ग्यूसेप

1
ऑपरेटरों की पूर्वता के आधार पर, आप कुछ फंकी सामान कर सकते हैं जो मदद कर सकते हैं; की <तुलना में कम पूर्वता है +, लेकिन *उच्च वरीयता है +ताकि आप संभावित रूप से उन्हें एक साथ श्रृंखला दे सकें!
ग्यूसेप

1
@Giuseppe आप जानते हैं कि मैंने पोस्ट करने से पहले क्या खोजने की कोशिश की और वह नहीं मिली। इस पर ध्यान दिलाने के लिए धन्यवाद। मैं उदाहरण के साथ ऑपरेटर पूर्वता पर अधिक विवरण जोड़ने की योजना बना रहा हूं क्योंकि मैं इस ट्रिक का अधिक से अधिक उपयोग करना शुरू करता हूं।
JayCe

2
यहाँ एक मजेदार एक है: यदि आप के लिए बाध्य ?करने के लिए pasteया किसी अन्य समारोह है कि दो तर्क ले जा सकते हैं, पूर्वता क्रम आप अभी भी के माध्यम से इनलाइन कार्य उपयोग कर सकते हैं a<-b?d<-e
जे। डी। ओ।

1
आपको [तीन-तत्व उर्फ ​​(दो बाइट्स) के रूप में जोड़ना चाहिए ; मुझे अक्सर यह चीजों के लिए मददगार लगता है outer(और लगातार इसके बारे में भूल जाते हैं!), हालांकि निश्चित रूप से आपको यह सुनिश्चित करने की आवश्यकता है कि आपको वास्तव में उपयोग करने की आवश्यकता नहीं है [। यह भी उर्फ चयन के साथ मदद करने के लिए ऑपरेटर पूर्वता पृष्ठ से जोड़ने के लिए उपयोगी होगा ।
ग्यूसेप

5

परिदृश्य जहाँ आप बच सकते हैं paste(...,collapse="") औरstrsplit

ये सामान्य स्ट्रिंग चुनौतियों में एक दर्द हैं। कुछ वर्कअराउंड हैं।

  • Reduce(paste0,letters) से -5 बाइट्स के लिए paste0(letters,collapse="")

  • एक 2-बाइट गोल्फ जहां दो वैक्टर युक्त एक सूची है c(1,2,3)और c(4,5,6)और उन्हें एक स्ट्रिंग के लिए तत्व के लिहाज से श्रेणीबद्ध करना चाहते हैं "142536"। ऑपरेटर दुरुपयोग आपको देता है p=paste0;"^"=Reduce;p^p^rजो सामान्य paste0कॉल पर दो बाइट्स बचाता है ।

  • paste0("(.{",n,"})")20 बाइट्स के लिए एक रेगेक्स के निर्माण (जैसे) के बजाय , एक रेगेक्स में एक रेगेक्स पर विचार करें: sub(0,"(.{0})",n)17 बाइट्स के लिए।

कभी-कभी (बहुत बार, वास्तव में) आपको वर्णों या तारों के वेक्टर के माध्यम से पुनरावृति करने की आवश्यकता होगी, या किसी शब्द को अक्षरों में विभाजित करना होगा। दो सामान्य उपयोग के मामले हैं: एक जहां आपको किसी फ़ंक्शन या प्रोग्राम के इनपुट के रूप में वर्णों की एक वेक्टर लेने की आवश्यकता होती है, और एक जहां आप वेक्टर को पहले से जानते हैं और कहीं इसे अपने कोड में संग्रहीत करने की आवश्यकता है।

ए। जहां आपको इनपुट के रूप में एक स्ट्रिंग लेने की जरूरत है और इसे शब्दों या वर्णों में विभाजित करें

  1. यदि आपको शब्दों की आवश्यकता है (विशेष मामले के रूप में वर्ण सहित):

    • यदि एक नई पंक्ति 0x10(ASCII 16) शब्दों को अलग करना ठीक है, x=scan(,"")तो अपने कोड को लपेटना पसंद किया जाता है function(s,x=el(strsplit(s," ")))

    • शब्दों द्वारा अलग किया जा सकता है, तो किसी अन्य खाली स्थान के एक से अधिक रिक्त स्थान, टैब, नई-पंक्तियों आदि सहित, आप @ एन जी एम के उपयोग कर सकते हैं डबल चाल स्कैन : x=scan(,"",t=scan(,""))। यह स्ट्रिंग में स्कैन scanको textआर्ग के रूप में देता है और इसे व्हाट्सएप द्वारा अलग करता है।

    • दूसरा तर्क scanकिसी भी प्रकार का हो सकता है इसलिए यदि आपने एक बनाया है, तो आप एक बाइट को बचाने के लिए उसे रीसायकल कर सकते हैं ।

  2. यदि आपको वर्णों के वेक्टर में एक इनपुट स्ट्रिंग चालू करने की आवश्यकता है :

    • x=el(strsplit(s,""))सबसे छोटा सामान्य उपाय है। splitतर्क सहित लंबाई शून्य से कुछ भी पर काम करता है c(), {}आदि इसलिए यदि आप एक शून्य लम्बाई चर बनाया है के लिए हो, तो आप इसे इस्तेमाल कर सकते हैं एक बाइट को बचाने के लिए।

    • यदि आप ASCII वर्ण कोड के साथ काम कर सकते हैं, तो विचार करें utf8ToInt, चूंकि कॉल utf8ToInt(x)से कम है strsplit। उन्हें वापस एक साथ चिपकाने के लिए, intToutf8(utf8ToInt(x))की तुलना में कम है Reduce(paste0,el(strsplit(x,"")))

    • यदि आपको "31415926535"इनपुट के रूप में संख्याओं के मनमाने तार को विभाजित करने की आवश्यकता है , तो आप utf8ToInt(s)-483 बाइट्स को बचाने के लिए उपयोग कर सकते हैं el(strsplit(s,"")), बशर्ते कि आप वर्णों के बजाय पूर्णांक अंकों का उपयोग कर सकते हैं, जैसा कि अक्सर होता है। यह दशमलव अंकों में संख्याओं को विभाजित करने के सामान्य नुस्खा से भी छोटा है।

ख। जहां आपको पहले से किसी भी शब्द या वर्ण के निश्चित वेक्टर की आवश्यकता होती है ।

  • आप कुछ नियमित पैटर्न या वर्णमाला क्रम में हैं कि, का उपयोग कर देखो एकल पात्रों में से एक सदिश की जरूरत है intToUtf8या chartrके माध्यम से एक दृश्य के लिए आवेदन किया a:bया पत्र सेट में बनाया पर lettersया LETTERS। पैटर्न में बनाया भाषा chartrहै विशेष रूप से शक्तिशाली

  • के लिए 1 से 3 अक्षर या शब्द , c("a","b","c")केवल सामान्य कम से कम समाधान है।

  • आप की एक निश्चित वेक्टर की जरूरत है 4 और 10 के बीच गैर खाली स्थान के वर्ण या शब्द , का उपयोग scanके साथ stdinके रूप में fileआर्ग:

f(x=scan(,""))
q
w
e
r
t
y
u
  • यदि scanसे stdinके लिए संभव नहीं है, 6 या अधिक गैर खाली स्थान के वर्ण या शब्द , का उपयोग scanके साथ textतर्क scan(,"",t="a b c d e f")

  • यदि आपको किसी भी प्रकार के (a) 6 या अधिक वर्णों के वेक्टर (b) 10 या अधिक गैर-व्हाट्सएप वर्णों की आवश्यकता है , strsplitतो x=el(strsplit("qwertyuiop",""))संभवतः जाने का रास्ता है।

  • आप निम्नलिखित उद्धरण चाल के साथ दूर जाने में सक्षम हो सकते हैं : जो कि अभिव्यक्ति बनाता है। कुछ फ़ंक्शंस जैसे , और इसे एक तार के वेक्टर के लिए मजबूर करेगा! यदि आप करते हैं, तो यह 3 या 11 से किसी भी शब्द या वर्ण वेक्टर की लंबाई के लिए अच्छा है।quote(Q(W,E,R,T,Y))strrepgrep

  • strsplitशब्दों के माध्यम से उपयोग करने का कोई अच्छा कारण नहीं है x=el(strsplit("q w e r t y"," "))। यह हमेशा scan(,"",t="q w e r t y"))5 बाइट्स के निश्चित ओवरहेड से हार जाता है।

यहां लंबाई के एकल वर्णों के वेक्टर में पढ़ने के लिए प्रत्येक दृष्टिकोण द्वारा उपयोग की जाने वाली बाइट काउंट की एक तालिका है n। प्रत्येक पंक्ति के भीतर संबंधी आदेश देने के अलावा, वर्ण या शब्द के लिए मान्य है strsplitपर ""जो केवल पात्रों पर काम करता है।

| n  | c(...) | scan | scan | strsplit | quote |
|    |        |+stdin|+text | on ""    | hack  |
|    |        |      |      | CHAR ONLY|       |
|----|--------|------|------|----------|-------|
| 1  | 3      | 11   | 15   | 20       | 8     |
| 2  | 10     | 13   | 17   | 21       | 11    |
| 3  | 14     | 15   | 19   | 22       | 13    |
| 4  | 18     | 17   | 21   | 23       | 15    |
| 5  | 22     | 19   | 23   | 24       | 17    |
| 6  | 26     | 21   | 25   | 25       | 19    |
| 7  | 30     | 23   | 27   | 26       | 21    |
| 8  | 34     | 25   | 29   | 27       | 23    |
| 9  | 38     | 27   | 31   | 28       | 25    |
| 10 | 42     | 29   | 33   | 29       | 27    |
| 11 | 46     | 31   | 35   | 30       | 29    |
| 12 | 50     | 33   | 37   | 31       | 31    |

सी। यदि आपको टेक्स्ट को एक वर्ण मैट्रिक्स के रूप में इनपुट करने की आवश्यकता है , तो कुछ व्यंजन जो छोटे लगते हैं

s="hello\nworld\n foo"

# 43 bytes, returns "" padded data frame
# If lines > 5 are longer than lines <= 5, wraps around and causes error
read.csv(t=gsub("(?<=.)(?=.)",",",s,,T),,F)

# 54 bytes with readLines(), "" padded matrix
sapply(p<-readLines(),substring,p<-1:max(nchar(p)),p))

# plyr not available on TIO
# 58 bytes, returns NA padded matrix, all words split by whitespace
plyr::rbind.fill.matrix(Map(t,strsplit(scan(,"",t=s),"")))
# 61 bytes, returns NA padded matrix
plyr::rbind.fill.matrix(Map(t,(a=strsplit)(el(a(s,"\n")),"")))

1
scanएक textतर्क है, जो el(strsplit(x," "))अगर आप केवल तार की जरूरत है की तुलना में अधिक प्रतिस्पर्धी है ! इसे ऑनलाइन आज़माएं! के रूप में अपने अंतिम सुझाव का विरोध किया read.csv
Giuseppe

यदि आप केवल वर्ण चाहते हैं, तो आपकी कॉल scan5 वर्णों तक बेहतर है, 6 या अधिक की el(strsplit(x,""))तुलना में अधिक प्रतिस्पर्धी है scanइसे ऑनलाइन आज़माएं! मुझे अभी तक इसके लिए एक अच्छा उपयोग नहीं मिला है read.csv, लेकिन शायद यह उपयोगी होगा यदि आपको किसी कारण से डेटा तालिका की आवश्यकता है?
जे। ओद

मैंने कभी इसका उपयोग नहीं किया है, data.frameलेकिन शायद हमें एक चुनौती खोजने / बनाने की आवश्यकता है जहां यह मददगार होगा! शायद एक dplyrशैली group_by()और summarize()हेरफेर का प्रकार? IDK।
Giuseppe

और तार में पढ़ने के लिए scan(,"")अभी भी बेहतर लगता है? इसे ऑनलाइन आज़माएं!
जे। ओद

हाँ, यह सुनिश्चित करने के लिए, हालाँकि यदि आप किसी इनपुट प्रारूप की कड़ाई से व्याख्या करते हैं जैसा कि यहाँ एनजीएम करता है तो डबल scanकाम होता है।
ग्यूसेप

4

सरणी के पहले गैर-शून्य तत्व को खोजने के कुछ तरीके।

यदि इसका कोई नाम है x:

x[!!x][1]

NAयदि कोई शून्य-शून्य तत्व ( xखाली होने पर भी) सहित वापस लौटाता है, लेकिन नहींNULL जो त्रुटियों।)

गुमनाम रूप से:

Find(c, c(0,0,0,1:3))

रिटर्न NULLअगर कोई गैर शून्य तत्वों, या खाली है या NULL


यह वापस आ जाएगा NAयदि सभी तत्व xशून्य हैं, मेरा मानना ​​है, इसलिए सावधानी के साथ इसका उपयोग करें!
Giuseppe

Find(c,x)एक ही बायटेकाउंट है: यदि आपको कोई मैच नहीं करना है, तो फायदा आपको दोहराने (परिभाषित) एक्स, और एक अलग व्यवहार करने की आवश्यकता नहीं है। TIO
JayCe

Findयह थोड़ा सुरक्षित भी है क्योंकि यह काम करता है NULL, जब तक कि परिणाम के लिए कुछ और करने की आवश्यकता नहीं होती है, जिस स्थिति में मुझे यकीन नहीं है कि लौट रहा है NAया NULLसुरक्षित है।
एनसीएम

ओह ये सही हैं। NULL को वापस करने के साथ समस्या त्रुटियां है ... संस्करण तुलनात्मक प्रश्न में मैंने पहली बार कोशिश की, sign(Find(c,w))जो त्रुटियों का कारण बना - इसे करने के लिए करना था Find(c,sign(w))त्रुटि नहीं। मुझे लगता है कि दोनों तरीकों के अपने उपयोग हैं।
JayCe

4

के लिए विकल्प rep()

कभी कभी rep() कोलन ऑपरेटर :और आर के वेक्टर रीसाइक्लिंग से बचा जा सकता है ।

  • दोहराने के लिए nशून्य को , जहां n>0, 0*1:n3 बाइट्स से कम हैrep(0,n) और !1:n, की एक सरणी FALSE, 4 बाइट्स छोटी है, यदि उपयोग इसे अनुमति देता है।

  • दोहराना x nबार-बार , x+!1:n2 बाइट्स से कम है rep(x,n)। के लियेn लोगों का उपयोग करें, !!1:nयदि आप की एक सरणी का उपयोग कर सकते TRUE

  • दोहराना x 2n+1बार-बार , जहां n>=0,x+0*-n:n 4 बाइट्स से कम है rep(x,2*n+1)

  • बयान दोनों तरफ से !-n:nएक TRUEफ्लैंक देगा n FALSE। इसका उपयोग किया जा सकता है कॉल में वर्णों की संख्या उत्पन्न करने के लिए है intToUtf8()यदि आपको याद है कि एक शून्य को अनदेखा किया गया है।

मॉड्यूलर अंकगणित उपयोगी हो सकता है। तर्क के repसाथ बयानों eachको कभी-कभी पूर्णांक विभाजन का उपयोग करके टाला जा सकता है।

  • वेक्टर उत्पन्न करने के लिए c(-1,-1,-1,0,0,0,1,1,1) , -3:5%/%35 बाइट्स से कम है rep(-1:1,e=3)

  • वेक्टर उत्पन्न करने के लिए c(0,1,2,0,1,2,0,1,2) , 0:8%%34 बाइट्स को बचाता है rep(0:2,3)

  • कभी-कभी गैर-रेखीय परिवर्तन अनुक्रम अंकगणितीय को छोटा कर सकते हैं। नक़्शा बनाने के लिए i in 1:15करने के लिए c(1,1,3,1,1,3,1,1,3,1,1,3,1,1,3)एक यौगिक बयान के अंदर, स्पष्ट golfy जवाब है 1+2*(!i%%3)11 बाइट्स के लिए। हालांकि, 3/(i%%3+1)है 10 बाइट्स , और उसी क्रम को इच्छा मंजिल, इसलिए यदि आप सरणी अनुक्रमण के लिए अनुक्रम की जरूरत है इसका इस्तेमाल किया जा सकता है।


3

जब आपको किसी फ़ंक्शन का उपयोग करने की आवश्यकता होती है, तो उपयोग करें pryr::f() इसके बजायfunction()

उदाहरण:

function(x,y){x+y}

के बराबर है

pryr::f(x,y,x+y)

या, और भी बेहतर,

pryr::f(x+y)

चूँकि यदि केवल एक तर्क है, तो कोड से सूत्र का अनुमान लगाया जाता है


जब तक आप इसे एक तर्क (तीसरे उदाहरण की तरह) में प्राप्त नहीं function(x,y){x+y}कर सकते , यह एक गोल्फ नहीं है, क्योंकि इसे function(x,y)x+yएक ही बायटेकाउंट के रूप में pryr::f(x,y,x+y)लेकिन अधिक पठनीयता के साथ लिखा जा सकता है ।
खुल्द्रेसथ ना'बर्या

3

तार से जुड़ी चुनौतियों से बचे

जैसा कि एक अन्य जवाब में उल्लेख किया गया है, unlist(strsplit(x,split="")और paste(...,collapse="")निराशाजनक हो सकता है। लेकिन इन से दूर मत चलो, वहाँ workarounds हैं!

  • utf8ToIntएक स्ट्रिंग को वेक्टर में परिवर्तित intToUtf8करता है, रिवर्स ऑपरेशन करता है। आप एक वेक्टर प्राप्त कर रहे हैं int, एक वेक्टर नहीं, charलेकिन कभी-कभी यह वही है जो आप खोज रहे हैं। उदाहरण के लिए -, की intToUtf8(rep(45,34))तुलना में बेहतर उपयोग उत्पन्न करने के लिएpaste(rep("-",34),collapse="")
  • gsubgrepपरिवार के अन्य कार्यों की तुलना में अधिक उपयोगी है जब एक ही तार पर काम किया जाता है। ऊपर दिए गए दो दृष्टिकोणों को इस उत्तर के रूप में जोड़ा जा सकता है जो ovs , Giuseppe और ngm की सलाह से लाभान्वित हुए
  • इस उत्तर में एक सुविधाजनक I / O प्रारूप चुनें जैसे कि पाठ की पंक्तियों (बिना उद्धरण) या इस एक के रूप में इनपुट लेना वर्णों का वेक्टर ले रहा है। संदेह होने पर ओपी से जांच कराएं।
  • जैसा कि टिप्पणियों में कहा गया है, <स्ट्रिंग्स की तुलनात्मक रूप से करें, जैसा कि कोई अपेक्षा करेगा।

intToUtf8एक दूसरा तर्क भी है multiple = FALSEजो intयदि सेट किया गया है तो एकल स्ट्रिंग के बजाय व्यक्तिगत अक्षरों (लंबाई-एक तार) से परिवर्तित होगा TRUE
ग्यूसेप

इसके अलावा, 3.5.0 में शुरू, वहाँ एक तीसरा तर्क है allow_surrogate_pairs = FALSE, लेकिन मुझे नहीं पता कि यह क्या करता है; डॉक्स दो-बाइट्स पढ़ने के बारे में कुछ कहते हैं, UTF-16लेकिन मैं मुश्किल से जानता हूं कि UTF-8ऐसा क्या है, मैं इसे तब तक अनदेखा कर दूंगा जब तक कि कोई और इसके साथ गोल्फ का रास्ता न खोज ले।
ग्यूसेप

2

प्रतिबंधित स्रोत चुनौतियों के लिए युक्तियाँ:

  1. R शाब्दिक स्थिरांक में वर्णों को हेक्स कोड, अष्टक कोड और यूनिकोड द्वारा प्रतिस्थापित किया जा सकता है।

    उदाहरण के लिए स्ट्रिंग "abcd"लिखा जा सकता है:

        # in octal codes
        "\141\142\143\144"
    
        # in hex codes
        "\x61\x62\x63\x64"
    
        # in unicodes
         "\u61\u62\u63\u64"
        # or
        "\U61\U62\U63\U64" 

    हम अष्टक / हेक्स / यूनिकोड के साथ वर्ण भी मिला सकते हैं और कुछ ऑक्ट कोड और कुछ हेक्स कोड का एक साथ उपयोग कर सकते हैं, जब तक कि यूनिकोड वर्ण ऑक्टल / हेक्स के साथ मिश्रित नहीं होते हैं:

        # Valid
        "a\142\x63\x64"
    
        # Valid
        "ab\u63\U64"
    
        # Error: mixing Unicode and octal/hex escapes in a string is not allowed
        "\141\142\x63\u64"

    देखें इस खंड के अंत अधिक जानकारी के लिए।

  2. चूंकि स्ट्रिंग स्ट्रिंग शाब्दिक का उपयोग करके फ़ंक्शन लिखे जा सकते हैं, उदाहरण के लिए cat()वैकल्पिक रूप से लिखा जा सकता है:

    'cat'()
    "cat"()
    `cat`()

    हम ऑक्टल कोड, हेक्स कोड और यूनिकोड को फ़ंक्शन नामों के लिए भी उपयोग कर सकते हैं:

    # all equal to cat()
    "\143\141\164"()
    `\x63\x61\x74`()
    '\u63\u61\u74'()
    "ca\u74"()

    केवल अपवाद के साथ कि यूनिकोड अनुक्रम बैकटिक्स `` के अंदर समर्थित नहीं हैं

  3. गोल कोष्ठकों को गाली देने वाले ऑपरेटरों से बचा जा सकता है जैसे:

    cat('hello')
    
    # can be written as
    `+`=cat;+'hello'

तीनों तरकीबों का एक आवेदन इस उत्तर में पाया जा सकता है


इसके अलावा, संख्याओं को हेक्साडेसिमल में लिखा जा सकता है: 0xBऔर 0xbवापसी 11(बैकटिक्स या उद्धरण की कोई आवश्यकता नहीं)।
रॉबिन राइडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.