एक महीने में काम के दिनों का प्रतिशत


11

एक वर्ष और एक महीने को देखते हुए, उक्त माह में कार्य दिवसों का प्रतिशत ज्ञात करें। छुट्टियों या अन्य विशेष चीजों के संबंध में शुक्रवार के माध्यम से कार्य दिवस सोमवार हैं। ग्रेगोरियन कैलेंडर का उपयोग किया जाता है।

इनपुट

आईएसओ 8601 प्रारूप (YYYY-MM) में एक वर्ष और महीना। वर्ष में हमेशा चार अंक होते हैं, महीने में हमेशा दो अंक होते हैं। दिए गए वर्ष 1582 से पहले नहीं होंगे।

उत्पादन

दिए गए महीने में आउटपुट कार्य दिवसों (उपरोक्त परिभाषा के अनुसार) का प्रतिशत है, जो पूरी संख्या में है। कोई भी प्रतिशत चिह्न या आंशिक अंक नहीं है।

नमूना 1

Input                Output

2010-05              68

नमूना २

Input                Output

2010-06              73

नमूना ३

Input                Output

1920-10              68

नमूना ४

Input                Output

2817-12              68

एक सप्ताह बीत चुका है, एक जवाब स्वीकार कर लिया गया है। जिज्ञासु के लिए, हमारी प्रतियोगिता में मिले सबमिशन के आकार:

129 - जेड शेल
174 - वीबी.नेट
222 - सी
233 - सी
300 - सी

साथ ही हमारे अपने (अनरैंक) समाधान:

  75 - पॉवरशेल
  93 - रूबी
112 - बॉर्न शेल


2
मैं एक स्नातक छात्र हूँ, इसलिए ...echo 100
एमोरी

यहां तक ​​कि स्नातक छात्र भी अपने कार्य की मूल परिभाषा से बच नहीं सकते। और मैंने काम के दिनों को अलग तरीके से परिभाषित किया ;-)
जॉय

जवाबों:


4

64-बिट पर्ल, 67 68

पर्ल 5.10 या बाद में, साथ चलाएं perl -E 'code here'याperl -M5.010 filename

map{$d++,/^S/||$w++if$_=`date -d@ARGV-$_`}1..31;say int.5+100*$w/$d

कोड आकार में रियायतें:

  • स्थान-संवेदी: यह उन दिनों के कार्य के रूप में गिना जाता है, जिनका dateउत्पादन पूंजी एस के साथ शुरू नहीं होता LC_ALL=Cहै।
  • आउटपुट शुद्ध और अच्छी तरह से स्वरूपित होता है, लेकिन 31 से कम महीने के स्टेडर पर "कचरा" होता है। 2> /dev/nullअगर परेशान हो।
  • किसी कारण से, मेरा संस्करण date2817-12 को अमान्य महीना मानता है। कौन जानता था, GNU नया सर्वनाश होने वाला है! date2038 के बाद तारीखों के लिए 64 बिट निर्माण की आवश्यकता है । (धन्यवाद जॉय)

1
स्पष्ट रूप से इसे "सिफोस हेम्स" ने अपने शासन के दौरान समाप्त कर दिया था। रेफरी "पवित्र बाइबल का एक नया इतिहास"
मार्टिन

1
क्या हर साल 2038 के बाद टूट जाता है? फिर टा 64-बिट का निर्माण हो सकता है मदद की तारीख से निपटने के साथ कुछ braindead सत्ता की वजह से ;-) स्विचिंग
जॉय

@ जोई बिल्कुल यही है। पारितोषिक के लिए धन्यवाद!
जेबी

जेबी: सिर्फ एक अनुमान था और मैं वास्तव में सी से परे कुछ भी उम्मीद नहीं करता था अभी भी केवल 32-बिट पूर्णांक का उपयोग करता हूं जो एक अजीब सी हॉक के बाद सेकंड की गिनती करता है। हालांकि, ईमानदार होना, मैं तिथियों के बारे में आवश्यकता> 2038 वहाँ में वास्तव में इस उद्देश्य के लिए ;-) डाल
जॉय

3

PHP - 135

मैंने इसे PHP में बनाया है क्योंकि मुझे कुछ दिनों पहले इलाज के लिए इसी तरह की समस्या थी।

<?php $a=array(2,3,3,3,2,1,1);$t=strtotime($argv[1]);$m=date(t,$t);echo round((20+min($m-28,$a[date(w,strtotime('28day',$t))]))/$m*100)

(कुछ हद तक) अधिक कानूनी रूप से, और स्थिरांक के रूप में उपयोग किए जाने वाले स्थिरांक के बारे में नोटिस के बिना:

<?php
date_default_timezone_set('America/New_York');
$additionalDays = array(2, 3, 3, 3, 2, 1, 1);
$timestamp = strtotime($argv[1]);
$daysInMonth = date('t', $timestamp);
$limit = $daysInMonth - 28;
$twentyNinthDayIndex = date('w', strtotime("+28 days", $timestamp));
$add = $additionalDays[$twentyNinthDayIndex];
$numberOfWorkDays = 20 + min($limit, $add);
echo round($numberOfWorkDays / $daysInMonth * 100);
?>

यह एक महीने में कार्य दिवसों की संख्या की गणना करने के लिए एक बहुत ही सरल एल्गोरिथ्म द्वारा संभव बनाया गया है: 29 वें, 30 वें और 31 वें (यदि वे तिथियां मौजूद हैं) के कार्यदिवस की जाँच करें, और 20 जोड़ें।


महान एल्गोरिथ्म, खराब गोल्फिंग। समकालीन PHP 5.3.5 और का उपयोग करते हुए -R, यह दृष्टिकोण 86 बाइट्स (63.7%) तक नीचे हो सकता है: $a="2333211";echo.5+min(-8+$m=date(t,$t=strtotime($argn)),20+$a[date(w,$t)])/$m*100|0; गोल्फिंग चरण देखें।
टाइटस

80 बाइट्स:<?=.5+min(-8+$m=date(t,$t=strtotime($argn)),20+(5886>>date(w,$t)*2&3))/$m*100|0;
टाइटस

2

पायथन 152 वर्ण

from calendar import*
y,m=map(int,raw_input().split('-'))
c=r=monthrange(y,m)[1]
for d in range(1,r+1):
 if weekday(y,m,d)>4:c-=1
print '%.f'%(c*100./r)


2

विंडोज पॉवरशेल, 80

$x=$args;1..31|%{"$x-$_"|date -u %u -ea 0}|%{$a++
$b+=!!($_%6)}
[int]($b*100/$a)

क्या आप वाकई [int]गोल हैं? मुझे विश्वास है कि यह फर्श होगा।
zneak

@zneak: PowerShell C या C- व्युत्पन्न भाषा नहीं है। यह .NET के डिफॉल्ट राउंडिंग मोड का उपयोग करता है जो »राउंड टू निकटतम सम पूर्णांक« है। बस इसे आज़माएं: दोनों [int]1.5और [int]2.5उपज 2। यह सटीक व्यवहार अक्सर उन कार्यों में समस्याओं का कारण बनता है जहां फ़्लोर किए गए विभाजन आवश्यक होते हैं (जो तब एक अतिरिक्त की आवश्यकता होती है [Math]::Floor()), लेकिन इस मामले में यह चोट नहीं करता है और »यहां तक ​​कि राउंड भी« केवल उन संख्याओं पर लागू होता है .5जिनमें अंत यहां नहीं हो सकता है।
जॉय

अगर आपको यकीन है तो मुझे विश्वास है। मुझे उम्मीद है कि इसके बजाय सी # की तरह काम करना होगा, और मेरे पास कोई विंडोज मशीन नहीं है जिस पर घर पर परीक्षण किया जा सके।
zneak

@zneak: नहीं, निश्चित रूप से C # में काम नहीं करता है। [int]PowerShell में कुछ ऐसा है जो आमतौर पर किसी कास्ट :-) की तुलना में अधिक रूपांतरण होता है। ऐसी चीजें [int[]][char[]]'abc'भी काम करती हैं जिन्हें आप कई अन्य भाषाओं में काम करने के लिए नहीं कर सकते।
जॉय

नेक्रोबम्प लेकिन $input-> $argsएक बाइट बचाता है।
विस्कह

1

D: 186 वर्ण

auto f(S)(S s){auto d=Date.fromISOExtendedString(s~"-28"),e=d.endOfMonth;int n=20;while(1){d+=dur!"days"(1);if(d>e)break;int w=d.dayOfWeek;if(w>0&&w<6)++n;}return rndtol(n*100.0/e.day);}

अधिक कानूनी रूप से:

auto f(S)(S s)
{
    auto d = Date.fromISOExtendedString(s ~ "-28"), e = d.endOfMonth;
    int n = 20;

    while(1)
    {
        d += dur!"days"(1);

        if(d > e)
            break;

        int w = d.dayOfWeek;

        if(w > 0 && w < 6)
            ++n;
    }

    return rndtol(n * 100.0 / e.day);
}

1

अजगर - 142

from calendar import*
y,m=map(int,raw_input().split('-'))
f,r=monthrange(y,m)
print'%.f'%((r-sum(weekday(y,m,d+1)>4for d in range(r)))*100./r)

कैलेंडर बिट के लिए fR0DDY का धन्यवाद।


1

रूबी, 124 119 111

require 'date'
e=Date.civil *$*[0].split(?-).map(&:to_i),-1
p ((e+1<<1..e).count{|d|d.cwday<6}*1e2/e.day).round

कारण -1 "दिन" तर्क से पहले और वर्ष और माह splatting को रूबी 1.9 की आवश्यकता है ?-के लिए "-"। रूबी 1.8 के लिए, हमें 2 वर्ण जोड़ना चाहिए:

require 'date'
e=Date.civil *$*[0].split('-').map(&:to_i)<<-1
p ((e+1<<1..e).count{|d|d.cwday<6}*1e2/e.day).round

संपादित करें : @ डॉगबर्ट की मदद पर आधारित पांच पात्रों को शेव करें
संपादित करें : @ steenslag की मदद के आधार पर आठ और पात्रों को शेव करें


आप डी को डेट क्यों दे रहे हैं?
डॉगबर्ट

@ डॉगबर्ट व्हाट्स! एक समय से होल्डओवर जब मेरे पास दो Date.civils थे; धन्यवाद!
फोग्ज

'-'?-रूबी 1.9
डॉगबर्ट

@ डोग्बर्ट नाइस मैं उसे भी फेंक दूंगा। मुझे लगता है कि सप्ताह के दिनों को चुनने का एक छोटा तरीका होना चाहिए, लेकिन मैंने इसे अभी तक नहीं पाया है।
मेंढक

e + 1 << 1 ee.day + 1 की तुलना में तीन छोटा है
स्टेन्सलैग

1

PHP 5.2, 88 बाइट्स

हालांकि मैंने पहले ही 85 बाइट्स के लिए नीचे दिए गए समाधानों को हल कर दिया है (मुझे बस एक और मिल गया है), यहां मेरा अपना है:
मुझे संदेह है कि मैं यहां से तीन अन्य बाइट्स को निचोड़ सकता हूं।

$a=_4444444255555236666304777411;echo$a[date(t,$t=strtotime($argn))%28*7+date(N,$t)]+67;

STDIN से इनपुट लेता है: साथ चलाएं echo <yyyy>-<mm> | php -nR '<code>'

स्ट्रिंग $aप्रति माह ( date(t)पहले दिन) और महीने के पहले दिन का दिन ( date(N): सोमवार = 1, रविवार = 7) कार्य दिवस -67 के प्रतिशत तक; strtotimeइनपुट को UNIX टाइमस्टैम्प में परिवर्तित करता है; बाकी कोड हैशिंग करता है।

पुराने PHP 5 के लिए +1 बाइट: Nसाथ wऔर $a=_...;साथ बदलें $a="..."
PHP 4 के लिए एक और +3 बाइट्स: के .-1बाद डालें $argn

PHP 5.5 या बाद के लिए -5 बाइट्स (चुनौती पोस्ट करता है):
पहले सब कुछ निकालें echoऔर $aसाथ बदलें "4444444255555236666304777411"


खैर ... एक बाइट: के %7बजाय %28
टाइटस

0

REBOL - 118 113

w: b: 0 o: d: do join input"-01"while[d/2 = o/2][if d/7 < 6[++ w]++ b d: o + b]print to-integer round w / b * 100

Ungolfed:

w: b: 0 
o: d: do join input "-01"
while [d/2 = o/2] [
    if d/7 < 6 [++ w]
    ++ b
    d: o + b
]
print to-integer round w / b * 100

0

सी #, 158 बाइट्स

s=>{var d=DateTime.Parse(s);int i=0,t=DateTime.DaysInMonth(d.Year,d.Month),w=0;while(i<t)w-=-(int)d.AddDays(i++).DayOfWeek%6>>31;return Math.Round(1e2*w/t);};

बेनामी विधि जो आवश्यक प्रतिशत लौटाती है।

पूर्ण कार्यक्रम के साथ ungolfed, टिप्पणी विधि और परीक्षण मामलों:

using System;

class WorkingDayPercentage
{
    static void Main()
    {
        Func <string, double> f =
        s =>
        {
            var d = DateTime.Parse(s);                      // extracts a DateTime object from the supplied string
            int i = 0,                                      // index variable
                t = DateTime.DaysInMonth(d.Year, d.Month),  // number of total number of days in the specified month
                w = 0;                                      // number of working days in the month

            while (i < t)                                   // iterates through the days of the month
                w -= -(int)d.AddDays(i++).DayOfWeek%6 >> 31;// d.AddDays(i) is the current day
                                                            // i++ increments the index variable to go to the next day
                                                            // .DayOfWeek is an enum which hold the weekdays
                                                            // (int)..DayOfWeek gets the days's index in the enum
                                                            // note that 6 is Saturday, 0 is Sunday, 1 is Monday etc.
                                                            // (int)DayOfWeek % 6 converts weekend days to 0
                                                            // while working days stay strictly positive
                                                            // - changes the sign of the positive numbers
                                                            // >> 31 extracts the signum
                                                            // which is -1 for negative numbers (working days)
                                                            // weekend days remain 0
                                                            // w -= substracts the negative numbers
                                                            // equivalent to adding their modulus

            return Math.Round(1e2 * w / t);                 // the Math.round function requires a double or a decimal
                                                            // working days and total number of days are integers
                                                            // also, a percentage must be returned
                                                            // multiplying with 100.0 converts the expression to a double
                                                            // however, 1e2 is used to shorten the code
        };

        // test cases:
        Console.WriteLine(f("2010-05")); // 68
        Console.WriteLine(f("2010-06")); // 73
        Console.WriteLine(f("1920-10")); // 68
        Console.WriteLine(f("2817-12")); // 68
    }
}

वैकल्पिक फ़ंक्शन, जो कार्य दिवसों की संख्या में नकारात्मक मान जोड़ता है, बदले में साइन को बिना अतिरिक्त बाइट लागत के साथ बदलता है:

s=>{var d=DateTime.Parse(s);int i=0,t=DateTime.DaysInMonth(d.Year,d.Month),w=0;while(i<t)w+=-(int)d.AddDays(i++).DayOfWeek%6>>31;return-Math.Round(1e2*w/t);};

0

Oracle SQL, 110 बाइट्स

select round(100*sum(1-trunc(to_char(x+level-1,'d')/6))/sum(1))from dual,t connect by level<=add_months(x,1)-x

यह एक धारणा के साथ काम करता है कि इनपुट डेटा तालिका में dateडेटा प्रकार का उपयोग करके संग्रहीत किया जाता है , जैसे

with t as (select to_date('2010-06','yyyy-mm') x from dual)

0

एपीएल (Dyalog यूनिकोड) , 55 बाइट्स SBCS

बेनामी tacit उपसर्ग समारोह।

.5+100×2÷/(2 5)2{≢⍎⍕↓⍺↓¯2' ',cal' '@5⊢⍵⊣⎕CY'dfns'}¨⊂

 इसे संपूर्ण मानने के लिए दिनांक संलग्न करें

(2 5)2{ उस पर निम्नलिखित फ़ंक्शन लागू करें, लेकिन बाएं तर्कों के साथ [2,5]और 2:

⎕CY'dfns' "dfns" लाइब्रेरी की प्रतिलिपि बनाएँ

⍵⊣ तारीख के पक्ष में रिपोर्ट छोड़ें

' '@5⊢ 5 वें वर्ण ( -) को एक स्थान से बदलें

 निष्पादित करें कि दो-तत्व सूची प्राप्त करने के लिए

cal उस पर कैलेंडर फ़ंक्शन को कॉल करें

' ', उस के लिए रिक्त स्थान का एक स्तंभ प्रस्तुत करना

¯2⌽ अंतिम दो कॉलम (शनिवार) को सामने की ओर घुमाएं

⍺↓ पंक्तियों की बाईं-तर्क संख्या (2, शीर्ष) और कॉलम (यदि निर्दिष्ट हो; 5 = सत + सूर्य)

 लाइनों की सूची में मैट्रिक्स विभाजित

 प्रारूप (डबल रिक्ति के सम्मिलन के साथ समतल)

 निष्पादित (एक फ्लैट संख्यात्मक सूची में शेष दिन संख्या बदल जाता है)

 उन लोगों को

2÷/ प्रत्येक जोड़ी को विभाजित करें (केवल एक ही है)

100× सौ से गुणा करें

.5+ एक आधा जोड़ें

 मंज़िल

इसे ऑनलाइन आज़माएं!


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.